home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / gopher / mvs / old-versions / gopher.ggmvs.distrib.cntl.v2r1m1.Z / gopher.ggmvs.distrib.cntl.v2r1m1
Encoding:
Text File  |  1995-04-24  |  1.1 MB  |  14,139 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  2. //*------------------------------------------------------------------*/         
  3. //*                                                                  */         
  4. //* Copyright (c) The Charles Stark Draper Laboratory, Inc.,1992,1993*/         
  5. //*                                                                  */         
  6. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  7. //* including the implied warranties of merchantability and fitness, */         
  8. //* are expressly denied.                                            */         
  9. //*                                                                  */         
  10. //* Provided this copyright notice is included, this software may    */         
  11. //* be freely distributed and not offered for sale.                  */         
  12. //*                                                                  */         
  13. //* Changes or modifications may be made and used only by the maker  */         
  14. //* of same, and not further distributed.  Such modifications should */         
  15. //* be mailed to the author for consideration for addition to the    */         
  16. //* software and incorporation in subsequent releases.               */         
  17. //*                                                                  */         
  18. //*------------------------------------------------------------------*/         
  19. //*                                                                             
  20. //* MVS GOPHER client                                                           
  21. //*                                                                             
  22. //* Author:  Steve Bacher <seb1525@mvs.draper.com>                              
  23. //*                                                                             
  24. //* Date:  April, 1993                                                          
  25. //*                                                                             
  26. //*--------------------------------------------------------------------         
  27. //*                                                                             
  28. //* This job creates the GOPHER distribution libraries (PDS's).                 
  29. //*                                                                             
  30. //* Run this JCL to create the PDS's, after customizing to suit.                
  31. //* (Obviously, put in a good JOB statement first.)                             
  32. //* To customize the JCL, change the defaults on the //GGLOAD PROC              
  33. //* statement to your liking, particularly the PREFIX default.                  
  34. //* You might also want to change the final qualifiers of the PDS's             
  35. //* created - to do this, find the // EXEC GGLOAD statements and                
  36. //* change the value of the TO parameter.                                       
  37. //*                                                                             
  38. //* See the $$README file (of the CNTL PDS, first in this stream)               
  39. //* for the rest of the installation instructions.                              
  40. //*                                                                             
  41. //GGLOAD  PROC CLS='*',BS='6160',U='3380',V='',                                 
  42. //             TRK1='30',TRK2='10',DIR='35',RLSE='RLSE',                        
  43. //             PREFIX='GOPHER.INSTALL.'                                         
  44. //*                                                                             
  45. //IEBUPDTE EXEC PGM=IEBUPDTE,PARM=NEW                                           
  46. //SYSPRINT DD   SYSOUT=&CLS                                                     
  47. //SYSUT2   DD   DISP=(NEW,CATLG,DELETE),DSN=&PREFIX.&TO,                        
  48. //         DCB=(RECFM=FB,LRECL=80,BLKSIZE=&BS),                                 
  49. //         SPACE=(TRK,(&TRK1,&TRK2,&DIR),&RLSE),UNIT=&U,VOL=SER=&V              
  50. //*                                                                             
  51. //         PEND                                                                 
  52. //CNTL     EXEC GGLOAD,TRK1='5',TO='CNTL'                                       
  53. //SYSIN    DD DATA,DLM='?!'                                                     
  54. ./   ADD NAME=$$README,SSI=01100022                                             
  55.                                                                                 
  56. ------------------------------------------------------------------------        
  57.                                                                                 
  58.  Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992, 1993            
  59.                                                                                 
  60.  MVS Gopher Server originally by Shawn Hart (Univ. of Delaware).                
  61.                                                                                 
  62.  This software is provided on an "AS IS" basis.  All warranties,                
  63.  including the implied warranties of merchantability and fitness,               
  64.  are expressly denied.                                                          
  65.                                                                                 
  66.  Provided this copyright notice is included, this software may                  
  67.  be freely distributed and not offered for sale.                                
  68.                                                                                 
  69.  Changes or modifications may be made and used only by the maker                
  70.  of same, and not further distributed.  Such modifications should               
  71.  be mailed to the author for consideration for addition to the                  
  72.  software and incorporation in subsequent releases.                             
  73.                                                                                 
  74. ------------------------------------------------------------------------        
  75.                                                                                 
  76.  MVS Gopher Client - Version 2 Release 1 - March 1993                           
  77.                                                                                 
  78.  Author:          Steve Bacher <seb1525@mvs.draper.com>                         
  79.                                                                                 
  80.  MVS Gopher Server                                                              
  81.                                                                                 
  82.  Author:          Shawn Hart   <shawn.hart@mvs.udel.edu>                        
  83.  Enhancements:    Steve Bacher <seb1525@mvs.draper.com>                         
  84.  Customizations:  Lou Joseph   <CWMY5C@IRISHMVS.CC.ND.EDU>                      
  85.                                                                                 
  86. ------------------------------------------------------------------------        
  87.                                                                                 
  88.  Contents of PDS's belonging to Gopher distribution:                            
  89.                                                                                 
  90.  Member     PDS Type    Description                                             
  91.                                                                                 
  92.  $$README   CNTL        This file                                               
  93.  ACCESS     CNTL        Sample server access file                               
  94.  ALLOAD     CNTL        JCL to allocate GOPHER load library                     
  95.  COMPILEC   CNTL        JCL to compile and link C source for client             
  96.  COMPILES   CNTL        JCL to compile and link C source for server             
  97.  GOPHERD    CNTL        JCL to run the GOPHER server in batch (No TSO)          
  98.  GOPHERT    CNTL        JCL to run the GOPHER server in batch (w. TSO)          
  99.  HELP       CNTL        TSO Help for Gopher client (with XPROC support)         
  100.  HELQ       CNTL        TSO Help for Gopher client (without XPROC)              
  101.  INSTALLC   CNTL        How to install the GOPHER MVS client                    
  102.  INSTALLS   CNTL        How to install the GOPHER MVS server                    
  103.  MENU       CNTL        Initial Gopher server menu                              
  104.  PARMS      CNTL        Sample Gopher startup parameters                        
  105.  GOPHER     CLIST       Exec by which users invoke the Gopher client            
  106.  NNMFIUCV   CLIST       Exec to check for multiple socket applications          
  107.  HOSTNAME   CLIST       Sample "hostname" command for REXX feature              
  108.  TSOHELP    CLIST       Sample REXX exec for Gopher TSO HELP menu hole          
  109.  GGM...     PANEL       ISPF regular panels                                     
  110.  GG...      H           C headers for compilation                               
  111.  GG...      C           C source for compilation                                
  112.  ABOUT...   ABOUT       "About This Gopher" text                                
  113.                                                                                 
  114. --------------------------------------------------------------------            
  115.                                                                                 
  116. Where to Go from Here:                                                          
  117.                                                                                 
  118.  To install the GOPHER MVS client, read member INSTALLC.                        
  119.                                                                                 
  120.  To install the GOPHER MVS server, read member INSTALLS.                        
  121.                                                                                 
  122. Note:                                                                           
  123.                                                                                 
  124.  You may install only the client, only the server, or both the                  
  125.  client and the server.  It is purely up to what your needs are.                
  126.                                                                                 
  127. --------------------------------------------------------------------            
  128.                                                                                 
  129. Changes:                                                                        
  130.                                                                                 
  131.  10/19/92 - Improvements in initial startup and GOPHERRC customization          
  132.  12/07/92 - Customizations to support SNS/TCPAccess                             
  133.  03/20/93 - Version 2:  Improved browse function                                
  134.                         Printing support                                        
  135.                         Bookmark support                                        
  136.                         New commands: PRT, INFO, MENU, BOOKMARK                 
  137.                         Configurable startup parameter file                     
  138.                         Ability to run multiple servers on same MVS             
  139.                                                                                 
  140. --------------------------------------------------------------------            
  141.                                                                                 
  142.  Questions?  Comments?  Suggestions?  Gripes?  Please email to...               
  143.                                                                                 
  144.  Steve Bacher      <seb@draper.com> or <seb1525@mvs.draper.com>                 
  145.                                                                                 
  146. ./   ADD NAME=ACCESS,SSI=01020059                                               
  147. !                                                                               
  148. ! Format of entries:                                                            
  149. !                                                                               
  150. ! filename (fully qualified, all uppercase, no quotes)                          
  151. ! can be "DD:DDNAME" or "EXEC:EXECNAME"                                         
  152. !                                                                               
  153. ! followed by names of hosts which are authorized to access the data.           
  154. ! If no host name list is present, all hosts are authorized                     
  155. !                                                                               
  156. ! You may specify the same file name more than once, if you need                
  157. ! more lines to put host names on.                                              
  158. !                                                                               
  159. ! Individual PDS members must be specified separately.  A PDS without           
  160. ! a member name establishes access only to the PDS directory.                   
  161. !                                                                               
  162. ! Note that the default directory MUST be in this table.                        
  163. !                                                                               
  164. ! Also note that in the case of EXECs, the EXEC must live in the                
  165. ! library allocated to GGEXEC in the Gopher server JCL.                         
  166. !                                                                               
  167. ! *** ANY DATA SET REFERENCED BY ANY EXEC IN THAT LIBRARY IS FULLY              
  168. ! *** ACCESSIBLE TO GOPHER REGARDLESS OF THIS TABLE!  USE THIS TABLE            
  169. ! *** TO GOVERN CONTROL TO THE EXEC ITSELF!!!                                   
  170.                                                                                 
  171. !                                                                               
  172. ! below is default directory spec, which MUST be in this table                  
  173. !                                                                               
  174. DD:GGGOPHER                                                                     
  175.                                                                                 
  176. !                                                                               
  177. ! Use the following for "About This Gopher".                                    
  178. ! (Change the PDS name to match your installation.)                             
  179. ! Free free to specify the name of your MVS client host(s)                      
  180. ! for information pertinent to MVS only.  mvs1 and mvs2 are examples.           
  181. !                                                                               
  182. DD:GGABOUT                                                                      
  183. GOPHER.ABOUT(ABOUT)                                                             
  184. GOPHER.ABOUT(ABOUTC)                              mvs1 mvs2                     
  185. GOPHER.ABOUT(ABOUTCD)                             mvs1 mvs2                     
  186. GOPHER.ABOUT(ABOUTCF)                             mvs1 mvs2                     
  187. GOPHER.ABOUT(ABOUTCO)                             mvs1 mvs2                     
  188. GOPHER.ABOUT(ABOUTCQ)                             mvs1 mvs2                     
  189. GOPHER.ABOUT(ABOUTCS)                             mvs1 mvs2                     
  190. GOPHER.ABOUT(ABOUTCSC)                            mvs1 mvs2                     
  191. GOPHER.ABOUT(ABOUTCSL)                            mvs1 mvs2                     
  192. GOPHER.ABOUT(ABOUTCSM)                            mvs1 mvs2                     
  193. GOPHER.ABOUT(ABOUTCSR)                            mvs1 mvs2                     
  194. GOPHER.ABOUT(ABOUTCSW)                            mvs1 mvs2                     
  195. GOPHER.ABOUT(ABOUTCSX)                            mvs1 mvs2                     
  196. GOPHER.ABOUT(ABOUTCX)                             mvs1 mvs2                     
  197. GOPHER.ABOUT(ABOUTS)                              mvs1 mvs2                     
  198. GOPHER.ABOUT(ABOUTSA)                             mvs1 mvs2                     
  199. GOPHER.ABOUT(ABOUTW)                                                            
  200. GOPHER.ABOUT(FAQ)                                                               
  201.                                                                                 
  202. !                                                                               
  203. ! Here's how to do REXX execs.  Note - no arguments, only exec names            
  204. !                                                                               
  205. EXEC:CHECKLST                     client1 client2 mvs                           
  206. EXEC:WAISDIR                                                                    
  207. EXEC:WAISLIST                                                                   
  208. EXEC:WAISSRCH                                                                   
  209.                                                                                 
  210. ANY.PUBLIC.SEQ.DS                                                               
  211. ANY.SEMI.PUBLIC.SEQ.DS            goodclient1 goodclient2                       
  212. ANY.SEMI.PUBLIC.SEQ.DS            goodclient3 goodclient4                       
  213.                                                                                 
  214. ! PDS without member name provides access to directory only                     
  215. ! All member names must be explicitly listed to be accessible.                  
  216.                                                                                 
  217. ANY.PUBLIC.PDS                                                                  
  218. ANY.PUBLIC.PDS(MEMBER1)                                                         
  219. ANY.PUBLIC.PDS(MEMBER2)                                                         
  220. ANY.PUBLIC.PDS(MEMBER3)                                                         
  221. ANY.PUBLIC.PDS(MEMBER4)                                                         
  222.                                                                                 
  223.                                                                                 
  224. ANY.SEMI.PUBLIC.PDS               goodclient1 goodclient2                       
  225. ANY.SEMI.PUBLIC.PDS               goodclient3 goodclient4                       
  226. ANY.SEMI.PUBLIC.PDS(MEMBER1)      goodclient1                                   
  227. ANY.SEMI.PUBLIC.PDS(MEMBER2)      goodclient2                                   
  228. ANY.SEMI.PUBLIC.PDS(MEMBER3)      goodclient3                                   
  229. ANY.SEMI.PUBLIC.PDS(MEMBER4)      goodclient4                                   
  230.                                                                                 
  231. ./   ADD NAME=ALLOAD,SSI=01010051                                               
  232. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  233. //*                                                                  */         
  234. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  235. //*                                                                  */         
  236. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  237. //* including the implied warranties of merchantability and fitness, */         
  238. //* are expressly denied.                                            */         
  239. //*                                                                  */         
  240. //* Provided this copyright notice is included, this software may    */         
  241. //* be freely distributed and not offered for sale.                  */         
  242. //*                                                                  */         
  243. //* Changes or modifications may be made and used only by the maker  */         
  244. //* of same, and not further distributed.  Such modifications should */         
  245. //* be mailed to the author for consideration for addition to the    */         
  246. //* software and incorporation in subsequent releases.               */         
  247. //*                                                                  */         
  248. //*                                                                             
  249. //* Allocate GOPHER load library before install                                 
  250. //*                                                                             
  251. //GGALLOC PROC BS='6233',U='3380',V='',                                         
  252. //             PRI='100',SEC='100',DIR='35'                                     
  253. //*                                                                             
  254. //IEFBR14  EXEC PGM=IEFBR14                                                     
  255. //ALLOCDD  DD   DISP=(NEW,CATLG,DELETE),DSN=&LIB,                               
  256. //         DCB=(RECFM=U,BLKSIZE=&BS),                                           
  257. //         SPACE=(&BS,(&PRI,&SEC,&DIR)),UNIT=&U,VOL=SER=&V                      
  258. //*                                                                             
  259. //         PEND                                                                 
  260. //*                                                                             
  261. //* The following step allocates the load library from which the                
  262. //* executable program will be run.  If you intend to place the                 
  263. //* executable into an existing library, you can skip this step.                
  264. //* Otherwise, the name must match the name used on the LOADLIB                 
  265. //* parameter of the GGLINK procedure in the COMPILE JCL.                       
  266. //*                                                                             
  267. //* If you want separate libraries for the client and the server,               
  268. //* just dup this step and give 'em different lib names.                        
  269. //*                                                                             
  270. //ALLOC1   EXEC GGALLOC,PRI=50,SEC=50,DIR=35,                                   
  271. //         LIB='GOPHER.LOAD'                                                    
  272. //*                                                                             
  273. ./   ADD NAME=COMPILEC                                                          
  274. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  275. //*                                                                  */         
  276. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  277. //*                                                                  */         
  278. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  279. //* including the implied warranties of merchantability and fitness, */         
  280. //* are expressly denied.                                            */         
  281. //*                                                                  */         
  282. //* Provided this copyright notice is included, this software may    */         
  283. //* be freely distributed and not offered for sale.                  */         
  284. //*                                                                  */         
  285. //* Changes or modifications may be made and used only by the maker  */         
  286. //* of same, and not further distributed.  Such modifications should */         
  287. //* be mailed to the author for consideration for addition to the    */         
  288. //* software and incorporation in subsequent releases.               */         
  289. //*                                                                  */         
  290. //*********************************************************************         
  291. //*                                                                             
  292. //* Compile some or all GOPHER C/370 sources to make the SYSLIN input           
  293. //* to the linkedit of the executable Gopher load module(s).                    
  294. //*                                                                             
  295. //GGCC   PROC MEMBER=,                                                          
  296. //            SRCLIB='GOPHER.C',                 GOPHER C source PDS            
  297. //            HDRLIB='GOPHER.H',                 GOPHER C headers PDS           
  298. //            COMMHDR='TCPIP.COMMMAC',           C/370 TCP/IP headers           
  299. //            C370HDR='SYS1.EDCHDRS',            C/370 standard headers         
  300. //            SYSMSGS='SYS1.EDCMSGS',            C/370 messages file            
  301. //            SYSMSGM='EDCMSGE',                 C/370 message member           
  302. //            VIOUNIT=VIO,                       Temporary disk unit            
  303. //            OUTCLAS='*',                          SYSOUT class                
  304. //            CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters          
  305. //            TEST=TEST                             TEST or NOTEST              
  306. //*                                                                             
  307. //CCOMP     EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'                 
  308. //SYSMSGS   DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)                                  
  309. //SYSIN     DD DISP=SHR,DSN=&SRCLIB(&MEMBER)                                    
  310. //SYSLIB    DD DISP=SHR,DSN=&COMMHDR                                            
  311. //          DD DISP=SHR,DSN=&C370HDR                                            
  312. //USERLIB   DD DISP=SHR,DSN=&HDRLIB                                             
  313. //SYSLIN    DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),                     
  314. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  315. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  316. //SYSCPRT   DD SYSOUT=&OUTCLAS                                                  
  317. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  318. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  319. //SYSUT4    DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  320. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  321. //SYSUT6    DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  322. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  323. //SYSUT7    DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  324. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  325. //SYSUT8    DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  326. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  327. //SYSUT9    DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  328. //   SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)                 
  329. //SYSUT10   DD SYSOUT=&OUTCLAS                                                  
  330. //*                                                                             
  331. //         PEND                                                                 
  332. //*                                                                             
  333. //*********************************************************************         
  334. //*                                                                             
  335. //* Linkedit an executable Gopher load module.                                  
  336. //*                                                                             
  337. //* Note: If C/370 V1R2 or higher, and you have therefore accepted              
  338. //*       the "#define FETCH" in the GG header, you may delete                  
  339. //*       the line that includes the ISPLINK library.                           
  340. //*                                                                             
  341. //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries              
  342. //*       from the JCL and the AMPZMVSB card from the control deck.             
  343. //*                                                                             
  344. //GGLINK PROC LOADLIB='GOPHER.LOAD',             Executable load library        
  345. //            PLIBASE='SYS1.PLIBASE',            PL/1   link library            
  346. //            EDCBASE='SYS1.SEDCBASE',           C/370  link library            
  347. //            IBMBASE='SYS1.SIBMBASE',           PL/1+C common library          
  348. //            COMMTXT='TCPIP.COMMTXT',           TCP/IP link library            
  349. //            PASRUN3='SYS1.PAS.SAMPRUN3',       PASCAL link library            
  350. //            PASRUN1='SYS1.PAS.SAMPRUN1',       PASCAL link library            
  351. //            PASMSG1='SYS1.PAS.SAMPMSG1',       PASCAL link library            
  352. //            ISPLINK='ISP.V3R2M0.ISPLLIB',      ISPLINK link library           
  353. //            VIOUNIT=VIO,                       Temporary disk unit            
  354. //            OUTCLAS='*',                          SYSOUT class                
  355. //            LPARMS='LIST,LET,MAP',                Linkedit parameters         
  356. //            TEST=TEST                             TEST or NOTEST              
  357. //*                                                                             
  358. //LKED      EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'                        
  359. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  360. //SYSLIB    DD DISP=SHR,DSN=&PLIBASE                                            
  361. //          DD DISP=SHR,DSN=&EDCBASE                                            
  362. //          DD DISP=SHR,DSN=&IBMBASE                                            
  363. //          DD DISP=SHR,DSN=&COMMTXT                                            
  364. //          DD DISP=SHR,DSN=&PASRUN3  if TCP/IP V1 only                         
  365. //          DD DISP=SHR,DSN=&PASRUN1  if TCP/IP V1 only                         
  366. //          DD DISP=SHR,DSN=&PASMSG1  if TCP/IP V1 only                         
  367. //          DD DISP=SHR,DSN=&ISPLINK  if C/370 V1R1 with #undef FETCH           
  368. //SYSLMOD   DD DISP=SHR,DSN=&LOADLIB                                            
  369. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  370. //          SPACE=(32000,(30,30))                                               
  371. //*                                                                             
  372. //         PEND                                                                 
  373. //*                                                                             
  374. //GGCLIENT EXEC GGCC,MEMBER=GGCLIENT                                            
  375. //GGMALLOC EXEC GGCC,MEMBER=GGMALLOC                                            
  376. //GGMCLRTX EXEC GGCC,MEMBER=GGMCLRTX                                            
  377. //GGMCONN  EXEC GGCC,MEMBER=GGMCONN                                             
  378. //GGMCSO   EXEC GGCC,MEMBER=GGMCSO                                              
  379. //GGMDBM   EXEC GGCC,MEMBER=GGMDBM                                              
  380. //GGMDFAIL EXEC GGCC,MEMBER=GGMDFAIL                                            
  381. //GGMDIR   EXEC GGCC,MEMBER=GGMDIR                                              
  382. //GGMDISC  EXEC GGCC,MEMBER=GGMDISC                                             
  383. //GGMDISPL EXEC GGCC,MEMBER=GGMDISPL                                            
  384. //GGMDSOPT EXEC GGCC,MEMBER=GGMDSOPT                                            
  385. //GGMDUMP  EXEC GGCC,MEMBER=GGMDUMP                                             
  386. //GGMESRVR EXEC GGCC,MEMBER=GGMESRVR                                            
  387. //GGMFREEM EXEC GGCC,MEMBER=GGMFREEM                                            
  388. //GGMGETDS EXEC GGCC,MEMBER=GGMGETDS                                            
  389. //GGMGETM  EXEC GGCC,MEMBER=GGMGETM                                             
  390. //GGMGOFOR EXEC GGCC,MEMBER=GGMGOFOR                                            
  391. //GGMGSRVL EXEC GGCC,MEMBER=GGMGSRVL                                            
  392. //GGMIERR  EXEC GGCC,MEMBER=GGMIERR                                             
  393. //GGMIGET  EXEC GGCC,MEMBER=GGMIGET                                             
  394. //GGMINFO  EXEC GGCC,MEMBER=GGMINFO                                             
  395. //GGMISPF  EXEC GGCC,MEMBER=GGMISPF                                             
  396. //GGMIVGET EXEC GGCC,MEMBER=GGMIVGET                                            
  397. //GGMIVPUT EXEC GGCC,MEMBER=GGMIVPUT                                            
  398. //GGMMENU  EXEC GGCC,MEMBER=GGMMENU                                             
  399. //GGMMTFER EXEC GGCC,MEMBER=GGMMTFER                                            
  400. //GGMOUTS  EXEC GGCC,MEMBER=GGMOUTS                                             
  401. //GGMOUTTX EXEC GGCC,MEMBER=GGMOUTTX                                            
  402. //GGMPMSG  EXEC GGCC,MEMBER=GGMPMSG                                             
  403. //GGMPROC  EXEC GGCC,MEMBER=GGMPROC                                             
  404. //GGMSOCKT EXEC GGCC,MEMBER=GGMSOCKT                                            
  405. //GGMSOPT  EXEC GGCC,MEMBER=GGMSOPT                                             
  406. //GGMTNET  EXEC GGCC,MEMBER=GGMTNET                                             
  407. //GGMTSO   EXEC GGCC,MEMBER=GGMTSO                                              
  408. //GGMTYPE  EXEC GGCC,MEMBER=GGMTYPE                                             
  409. //GGMUNALC EXEC GGCC,MEMBER=GGMUNALC                                            
  410. //GGMVIEW  EXEC GGCC,MEMBER=GGMVIEW                                             
  411. //GGMVTX   EXEC GGCC,MEMBER=GGMVTX                                              
  412. //GGMWAIS  EXEC GGCC,MEMBER=GGMWAIS                                             
  413. //GGMWHOIS EXEC GGCC,MEMBER=GGMWHOIS                                            
  414. //GGMXTX   EXEC GGCC,MEMBER=GGMXTX                                              
  415. //*                                                                             
  416. //* Link GOPHER load module. Like SMP/E, expect return code 8 when              
  417. //* doing this from scratch.  Additional one-or-two-module links                
  418. //* will just replace the corresponding parts of the load module.               
  419. //*                                                                             
  420. //GGLINK EXEC GGLINK                                                            
  421. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  422. //            DD *                                                              
  423.  INCLUDE SYSLMOD(GGCLIENT)            if included first time, RC = 8            
  424.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  425.  ENTRY   CEESTART                                                               
  426.  NAME    GGCLIENT(R)                                                            
  427. /*                                                                              
  428. ./   ADD NAME=COMPILES,SSI=01060050                                             
  429. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  430. //*                                                                  */         
  431. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  432. //*                                                                  */         
  433. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  434. //* including the implied warranties of merchantability and fitness, */         
  435. //* are expressly denied.                                            */         
  436. //*                                                                  */         
  437. //* Provided this copyright notice is included, this software may    */         
  438. //* be freely distributed and not offered for sale.                  */         
  439. //*                                                                  */         
  440. //* Changes or modifications may be made and used only by the maker  */         
  441. //* of same, and not further distributed.  Such modifications should */         
  442. //* be mailed to the author for consideration for addition to the    */         
  443. //* software and incorporation in subsequent releases.               */         
  444. //*                                                                  */         
  445. //*********************************************************************         
  446. //*                                                                             
  447. //* Compile some or all GOPHER C/370 sources to make the SYSLIN input           
  448. //* to the linkedit of the executable Gopher load module.                       
  449. //*                                                                             
  450. //GGCC   PROC MEMBER=,                                                          
  451. //            SRCLIB='GOPHER.C',                 GOPHER C source PDS            
  452. //            HDRLIB='GOPHER.H',                 GOPHER C headers PDS           
  453. //            COMMHDR='TCPIP.COMMMAC',           C/370 TCP/IP headers           
  454. //            C370HDR='SYS1.EDCHDRS',            C/370 standard headers         
  455. //            SYSMSGS='SYS1.EDCMSGS',            C/370 messages file            
  456. //            SYSMSGM='EDCMSGE',                 C/370 message member           
  457. //            VIOUNIT=VIO,                       Temporary disk unit            
  458. //            OUTCLAS='*',                          SYSOUT class                
  459. //            CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters          
  460. //            TEST=TEST                             TEST or NOTEST              
  461. //*                                                                             
  462. //CCOMP     EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'                 
  463. //SYSMSGS   DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)                                  
  464. //SYSIN     DD DISP=SHR,DSN=&SRCLIB(&MEMBER)                                    
  465. //SYSLIB    DD DISP=SHR,DSN=&COMMHDR                                            
  466. //          DD DISP=SHR,DSN=&C370HDR                                            
  467. //USERLIB   DD DISP=SHR,DSN=&HDRLIB                                             
  468. //SYSLIN    DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),                     
  469. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  470. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  471. //SYSCPRT   DD SYSOUT=&OUTCLAS                                                  
  472. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  473. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  474. //SYSUT4    DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  475. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  476. //SYSUT6    DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  477. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  478. //SYSUT7    DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  479. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  480. //SYSUT8    DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  481. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  482. //SYSUT9    DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  483. //   SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)                 
  484. //SYSUT10   DD SYSOUT=&OUTCLAS                                                  
  485. //*                                                                             
  486. //         PEND                                                                 
  487. //*                                                                             
  488. //*********************************************************************         
  489. //*                                                                             
  490. //* Linkedit the executable Gopher load modules.                                
  491. //*                                                                             
  492. //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries              
  493. //*       from the JCL and the AMPZMVSB card from the control deck.             
  494. //*                                                                             
  495. //GGLINK PROC LOADLIB='GOPHER.LOAD',             Executable load library        
  496. //            EDCBASE='SYS1.SEDCBASE',           C/370  link library            
  497. //            IBMBASE='SYS1.SIBMBASE',           PL/1+C common library          
  498. //            COMMTXT='TCPIP.COMMTXT',           TCP/IP link library            
  499. //            PASRUN3='SYS1.PAS.SAMPRUN3',       PASCAL link library            
  500. //            PASRUN1='SYS1.PAS.SAMPRUN1',       PASCAL link library            
  501. //            PASMSG1='SYS1.PAS.SAMPMSG1',       PASCAL link library            
  502. //            IKJLINK='SYS1.LINKLIB',            IKJEFF18 link library          
  503. //            VIOUNIT=VIO,                       Temporary disk unit            
  504. //            OUTCLAS='*',                          SYSOUT class                
  505. //            LPARMS='LIST,LET,MAP',                Linkedit parameters         
  506. //            TEST=TEST                             TEST or NOTEST              
  507. //*                                                                             
  508. //LKED      EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'                        
  509. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  510. //SYSLIB    DD DISP=SHR,DSN=&EDCBASE                                            
  511. //          DD DISP=SHR,DSN=&IBMBASE                                            
  512. //          DD DISP=SHR,DSN=&COMMTXT                                            
  513. //          DD DISP=SHR,DSN=&PASRUN3  if TCP/IP V1 only                         
  514. //          DD DISP=SHR,DSN=&PASRUN1  if TCP/IP V1 only                         
  515. //          DD DISP=SHR,DSN=&PASMSG1  if TCP/IP V1 only                         
  516. //          DD DISP=SHR,DSN=&IKJLINK  if C/370 V1R1 with #undef FETCH           
  517. //SYSLMOD   DD DISP=SHR,DSN=&LOADLIB                                            
  518. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  519. //          SPACE=(32000,(30,30))                                               
  520. //*                                                                             
  521. //         PEND                                                                 
  522. //*                                                                             
  523. //GGMALLOC EXEC GGCC,MEMBER=GGMALLOC                                            
  524. //GGMDFAIL EXEC GGCC,MEMBER=GGMDFAIL                                            
  525. //GGMUNALC EXEC GGCC,MEMBER=GGMUNALC                                            
  526. //GGMOUTS  EXEC GGCC,MEMBER=GGMOUTS                                             
  527. //GGMPROC  EXEC GGCC,MEMBER=GGMPROC                                             
  528. //GGSTASK  EXEC GGCC,MEMBER=GGSTASK                                             
  529. //*                                                                             
  530. //* Link GOPHER subtask module.  Like SMP/E, expect return code 8               
  531. //* doing this from scratch.  Additional one-or-two-module links                
  532. //* will just replace the corresponding parts of the load module.               
  533. //*                                                                             
  534. //* If recompiling the entire load module, you may want to delete               
  535. //* the previous one from the SYSLMOD library first, or remove the              
  536. //* INCLUDE SYSLMOD card from the JCL below.                                    
  537. //*                                                                             
  538. //GGLINKT EXEC GGLINK                                                           
  539. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  540. //            DD *                                                              
  541.  INCLUDE SYSLMOD(GGSTASK)             if included first time, RC = 8            
  542.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  543.  INCLUDE SYSLIB(IUCVFORC)                                                       
  544.  INCLUDE SYSLIB(EDCMTFS)                                                        
  545.  ENTRY   CEESTART                                                               
  546.  NAME    GGSTASK(R)                                                             
  547. /*                                                                              
  548. //GGMMTFER EXEC GGCC,MEMBER=GGMMTFER                                            
  549. //GGSERVER EXEC GGCC,MEMBER=GGSERVER                                            
  550. //*                                                                             
  551. //* Link GOPHER server module.  Like SMP/E, expect return code 8                
  552. //* doing this from scratch.  Additional one-or-two-module links                
  553. //* will just replace the corresponding parts of the load module.               
  554. //*                                                                             
  555. //* If recompiling the entire load module, you may want to delete               
  556. //* the previous one from the SYSLMOD library first, or remove the              
  557. //* INCLUDE SYSLMOD card from the JCL below.                                    
  558. //*                                                                             
  559. //GGLINKS EXEC GGLINK                                                           
  560. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  561. //            DD *                                                              
  562.  INCLUDE SYSLMOD(GGSERVER)            if included first time, RC = 8            
  563.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  564.  ENTRY   CEESTART                                                               
  565.  NAME    GGSERVER(R)                                                            
  566. /*                                                                              
  567. ./   ADD NAME=GOPHERD,SSI=01070018                                              
  568. //GOPHERD  PROC MODULE=GGSERVER,                                        00010000
  569. //         STEPLIB='GOPHER.LOAD',                                       00020000
  570. //         EXECLIB='GOPHER.EXEC',                                       00030000
  571. //         ACCESS='GOPHER.ACCESS',                                      00040000
  572. //         ABOUT='GOPHER.ABOUT',                                        00050000
  573. //         MENU='GOPHER.MENU',                                          00050000
  574. //         PARMS='GOPHER.PARMS',                                                
  575. //         VIO=SYSVIO,                                                          
  576. //         STDERR='*',                                                          
  577. //         STDOUT='*',                                                          
  578. //         GPARM=                                                       00050000
  579. //*                                                                     00060000
  580. //********************************************************************* 00070000
  581. //*                                                                   * 00080000
  582. //* GOPHER daemon, by Shawn Hart (U.Del.) and Steve Bacher (D.Lab.)   * 00090000
  583. //*                                                                   * 00100000
  584. //* Straight batch (no TSO access)                                    * 00100000
  585. //*                                                                   * 00100000
  586. //********************************************************************* 00110000
  587. //*                                                                     00120000
  588. //GOPHERD  EXEC PGM=&MODULE,PARM='&GPARM'                               00150001
  589. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                   00170000
  590. //GGEXEC   DD   DISP=SHR,DSN=&EXECLIB                                   00181002
  591. //SYSTSPRT DD   UNIT=&VIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255             
  592. //SYSERR   DD   SYSOUT=&STDERR                                                  
  593. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  594. //SYSTSIN  DD   DUMMY                                                   00210000
  595. //SYSIN    DD   DUMMY                                                   00210000
  596. //GGDEBUG  DD   SYSOUT=*                                                00230000
  597. //GGABOUT  DD   DISP=SHR,DSN=&ABOUT                                     00230000
  598. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                    00240000
  599. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                      00250000
  600. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  601. ./   ADD NAME=GOPHERT,SSI=01050012                                              
  602. //GOPHERD  PROC MODULE=GGSERVER,                                        00010000
  603. //         STEPLIB='GOPHER.LOAD',                                       00020000
  604. //         EXECLIB='GOPHER.EXEC',                                       00030000
  605. //         ACCESS='GOPHER.ACCESS',                                      00040000
  606. //         ABOUT='GOPHER.ABOUT',                                        00050000
  607. //         MENU='GOPHER.MENU',                                          00050000
  608. //         PARMS='GOPHER.PARMS',                                                
  609. //         VIO=SYSVIO,                                                          
  610. //         STDERR='*',                                                          
  611. //         STDOUT='*',                                                          
  612. //         GPARM=                                                       00050000
  613. //*                                                                     00060000
  614. //********************************************************************* 00070000
  615. //*                                                                   * 00080000
  616. //* GOPHER daemon, by Shawn Hart (U.Del.) and Steve Bacher (D.Lab.)   * 00090000
  617. //*                                                                   * 00100000
  618. //********************************************************************* 00110000
  619. //*                                                                     00120000
  620. //GOPHERD  EXEC PGM=IKJEFT01,DYNAMNBR=128,REGION=8M,                    00150001
  621. //         PARM='&MODULE &GPARM'                                        00160000
  622. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                   00170000
  623. //GGEXEC   DD   DISP=SHR,DSN=&EXECLIB                                   00181002
  624. //SYSTSPRT DD   UNIT=&VIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255             
  625. //SYSERR   DD   SYSOUT=&STDERR                                                  
  626. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  627. //SYSTSIN  DD   DUMMY                                                   00220000
  628. //SYSIN    DD   DUMMY                                                   00230000
  629. //GGDEBUG  DD   SYSOUT=*                                                00230000
  630. //GGABOUT  DD   DISP=SHR,DSN=&ABOUT                                     00230000
  631. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                    00240000
  632. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                      00250000
  633. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  634. ./   ADD NAME=HELP,SSI=01010013                                                 
  635. )F Function -                                                                   
  636.                                                                                 
  637.  GOPHER is a distributed document delivery service, or, more generally,         
  638.  a networked information retrieval service.  It allows you to access            
  639.  numerous types of data on various hosts in a transparent fashion.              
  640.  GOPHER presents you with a hierarchical display of information sources         
  641.  which are accessed via a client/server communications link.                    
  642.                                                                                 
  643.  There are GOPHER clients for all common hardware platforms.  The MVS           
  644.  version runs as an ISPF dialog application.                                    
  645.                                                                                 
  646.  When you use the GOPHER client, information about your use of GOPHER           
  647.  is stored in a data set called GOPHERRC.  If you don't have one,               
  648.  GOPHER will create it for you.                                                 
  649.                                                                                 
  650.  You can save Gopher information in bookmark files.  See the                    
  651.  help for operand BOOKMARK for details.                                         
  652.                                                                                 
  653.  For more information on customizing your GOPHER environment, get               
  654.  into Gopher and select "About This GOPHER".                                    
  655.                                                                                 
  656. )I GOPHLOC          - local GOPHER help goes in member GOPHLOC                  
  657.                                                                                 
  658. )X Syntax -                                                                     
  659.                                                                                 
  660.    %GOPHER                                                                      
  661.               LOCAL                                                             
  662.               BOOKMARK(datasetname)                                             
  663.               SERVER(hostname)                                                  
  664.               PATH(pathname)                                                    
  665.               PORT(portnumber)                                                  
  666.               DESCRIPTION(text)                                                 
  667.               FORCE                                                             
  668.               DEBUG                                                             
  669.               TEST                                                              
  670.                                                                                 
  671.    Required:  none                                                              
  672.                                                                                 
  673. )O Operands -                                                                   
  674.                                                                                 
  675. ))LOCAL                                                                         
  676.                                                                                 
  677.               Specify LOCAL if you want to enter GOPHER in "serverless"         
  678.               mode - i.e. start up with your private GOPHER menu.               
  679.               Specifying LOCAL accomplishes two things:                         
  680.                                                                                 
  681.                (1) It sets the server to "-", meaning local access.             
  682.                    Therefore, you must also provide a path, either              
  683.                    via the PATH operand or via a "localmenu:" spec              
  684.                    in your GOPHERRC file.                                       
  685.                                                                                 
  686.                (2) It allows you to use GOPHER even if there are                
  687.                    other TCP/IP socket applications active elsewhere            
  688.                    in your TSO session.  However, it will not allow             
  689.                    you to connect to any GOPHER servers, even if you            
  690.                    have a local menu item that points to one.                   
  691.                                                                                 
  692.               For information on how to set up GOPHER menus, get into           
  693.               GOPHER and select "About This Gopher".                            
  694.                                                                                 
  695. ))BOOKMARK(datasetname)                                                         
  696.                                                                                 
  697.               The name of a data set containing Gopher bookmarks,               
  698.               using normal TSO data set naming conventions.                     
  699.                                                                                 
  700.               You can create bookmarks in GOPHER by using the "B"               
  701.               selection code next to a menu item, or by using the               
  702.               BOOKMARK command while browsing an entry.  GOPHER will            
  703.               append an entry for the selected item to the end of               
  704.               the data set that you specify when asked.                         
  705.                                                                                 
  706.               To access this bookmark in a Gopher session, you can use          
  707.               the MENU command from any Gopher menu display, or you can         
  708.               start Gopher with a specific bookmark file.                       
  709.                                                                                 
  710. ))SERVER(hostname)                                                              
  711.                                                                                 
  712.               The host name (or IP address) of a Gopher server.                 
  713.               If this is not given, GOPHER looks in your GOPHERRC               
  714.               to find what server to connect to.  If it can't find              
  715.               an appropriate specification, you will have to enter              
  716.               a server name on the startup panel.                               
  717.                                                                                 
  718.               A server name of a single minus sign (-) is a special             
  719.               case, signifying local (serverless) access to your                
  720.               own private GOPHER data.  In this case, you must tell             
  721.               GOPHER where your menu is, either via the PATH operand            
  722.               or in the GOPHERRC file.                                          
  723.                                                                                 
  724. ))PATH(pathname)                                                                
  725.                                                                                 
  726.               The path name to be passed to the Gopher server, or               
  727.               used in local access as your initial menu.  Although              
  728.               the exact interpretation of the pathname string varies            
  729.               depending on the server, both the MVS server and the              
  730.               local GOPHER access feature interpret the pathname                
  731.               as the FULLY QUALIFIED WITHOUT QUOTES name of an MVS              
  732.               data set containing a gopher menu.  For information               
  733.               about the format of a gopher menu, see operand MENU.              
  734.                                                                                 
  735. ))PORT(portnumber)                                                              
  736.                                                                                 
  737.               You should never need to specify this field unless                
  738.               someone has set up a special kind of Gopher server that           
  739.               requires a unique port number.  In such a case, you               
  740.               would generally use this along with the SERVER operand.           
  741.                                                                                 
  742. ))DESCRIPTION(text)                                                             
  743.                                                                                 
  744.               A text string giving the heading to be displayed for              
  745.               the initial directory of Gopher goodies.  Normally                
  746.               either the Gopher server or the Gopher client will                
  747.               have a default value for this, or you can specify                 
  748.               a description of your liking in your GOPHERRC file.               
  749.               You can also use this to override the description                 
  750.               generated when you use the BOOKMARK operand to start up.          
  751.                                                                                 
  752. ))FORCE                                                                         
  753.                                                                                 
  754.               GOPHER tries to determine if there is a TCP/IP socket             
  755.               application active elsewhere in your TSO environment              
  756.               before starting up, to prevent TCP/IP errors.  If it              
  757.               tells you that there is another client active but in              
  758.               truth there is none and you know it, you can use the              
  759.               FORCE keyword to make GOPHER proceed whether it finds             
  760.               this to be the case or not.                                       
  761.                                                                                 
  762.               Using the LOCAL operand is one way to avoid this entire           
  763.               scenario.  However, that won't allow you to access any            
  764.               Gopher servers on the network.                                    
  765.                                                                                 
  766. ))DEBUG                                                                         
  767.                                                                                 
  768.               Set debugging mode on.  You must preallocate a file to            
  769.               ddname GGDEBUG for this to work.  This can be allocated           
  770.               to the terminal or a log file.  When debug mode is on,            
  771.               messages describing memory allocation and deallocation            
  772.               and GOPHER queries sent are dumped to the debug file.             
  773.                                                                                 
  774. ))TEST                                                                          
  775.                                                                                 
  776.               Activate C/370 interactive test (INSPECT).  GOPHER must           
  777.               have been compiled with the TEST option for this to be            
  778.               effective.  Note that you can also issue the TEST command         
  779.               inside GOPHER to get to INSPECT, again provided that              
  780.               GOPHER was compiled with the TEST option.                         
  781.                                                                                 
  782. ./   ADD NAME=HELQ,SSI=01000025                                                 
  783. )F Function -                                                                   
  784.                                                                                 
  785.  GOPHER is a distributed document delivery service, or, more generally,         
  786.  a networked information retrieval service.  It allows you to access            
  787.  numerous types of data on various hosts in a transparent fashion.              
  788.  GOPHER presents you with a hierarchical display of information sources         
  789.  which are accessed via a client/server communications link.                    
  790.                                                                                 
  791.  There are GOPHER clients for all common hardware platforms.  The MVS           
  792.  version runs as an ISPF dialog application.                                    
  793.                                                                                 
  794.  When you use the GOPHER client, information about your use of GOPHER           
  795.  is stored in a data set called GOPHERRC.  If you don't have one,               
  796.  GOPHER will create it for you.                                                 
  797.                                                                                 
  798.  For more information on customizing your GOPHER environment, get               
  799.  into Gopher and select "About This GOPHER".                                    
  800.                                                                                 
  801. )I GOPHLOC          - local GOPHER help goes in member GOPHLOC                  
  802.                                                                                 
  803. )X Syntax -                                                                     
  804.                                                                                 
  805.    %GOPHER                                                                      
  806.               LOCAL                                                             
  807.               FORCE                                                             
  808.               DEBUG                                                             
  809.               TEST                                                              
  810.                                                                                 
  811.    Required:  none                                                              
  812.                                                                                 
  813. )O Operands -                                                                   
  814.                                                                                 
  815. ))LOCAL                                                                         
  816.                                                                                 
  817.               Specify LOCAL if you want to enter GOPHER in "serverless"         
  818.               mode - i.e. start up with your private GOPHER menu.               
  819.               Specifying LOCAL accomplishes two things:                         
  820.                                                                                 
  821.                (1) It sets the server to "-", meaning local access.             
  822.                    Therefore, you must also provide a path via a                
  823.                    "localmenu:" spec in your GOPHERRC file.                     
  824.                                                                                 
  825.                (2) It allows you to use GOPHER even if there are                
  826.                    other TCP/IP socket applications active elsewhere            
  827.                    in your TSO session.  However, it will not allow             
  828.                    you to connect to any GOPHER servers, even if you            
  829.                    have a local menu item that points to one.                   
  830.                                                                                 
  831.               For information on how to set up GOPHER menus, get into           
  832.               GOPHER and select "About This Gopher".                            
  833.                                                                                 
  834. ))FORCE                                                                         
  835.                                                                                 
  836.               GOPHER tries to determine if there is a TCP/IP socket             
  837.               application active elsewhere in your TSO environment              
  838.               before starting up, to prevent TCP/IP errors.  If it              
  839.               tells you that there is another client active but in              
  840.               truth there is none and you know it, you can use the              
  841.               FORCE keyword to make GOPHER proceed whether it finds             
  842.               this to be the case or not.                                       
  843.                                                                                 
  844.               Using the LOCAL operand is one way to avoid this entire           
  845.               scenario.  However, that won't allow you to access any            
  846.               Gopher servers on the network.                                    
  847.                                                                                 
  848. ))DEBUG                                                                         
  849.                                                                                 
  850.               Set debugging mode on.  You must preallocate a file to            
  851.               ddname GGDEBUG for this to work.  This can be allocated           
  852.               to the terminal or a log file.  When debug mode is on,            
  853.               messages describing memory allocation and deallocation            
  854.               and GOPHER queries sent are dumped to the debug file.             
  855.                                                                                 
  856. ))TEST                                                                          
  857.                                                                                 
  858.               Activate C/370 interactive test (INSPECT).  GOPHER must           
  859.               have been compiled with the TEST option for this to be            
  860.               effective.  Note that you can also issue the TEST command         
  861.               inside GOPHER to get to INSPECT, again provided that              
  862.               GOPHER was compiled with the TEST option.                         
  863.                                                                                 
  864. ./   ADD NAME=INSTALLC,SSI=01070035                                             
  865.                                                                                 
  866.  Directions for Installing the GOPHER MVS Client                                
  867.                                                                                 
  868.  Assuming the PDS's have been created:                                          
  869.                                                                                 
  870.  1. Customize the ALLOAD and COMPILEC JCL members to reflect your               
  871.  local conventions.  Note:  If you intend to place the executable into          
  872.  an existing library, you can suppress that part of the ALLOAD JCL.             
  873.  The name of the data set created must match across both members.               
  874.                                                                                 
  875.  2. Customize the GGUSER header file as shown by the comments therein.          
  876.  Note in particular the defines for your TCP/IP and your C compiler.            
  877.  There are changes to the linkedit JCL that are related to these.               
  878.                                                                                 
  879.  3.  Customize the GOPHER exec to define the names of the MVS libraries         
  880.  to contain the panel and load library members.  The load library must          
  881.  be the one specified in the ALLOAD JCL, if you are creating it anew.           
  882.  Observe the comments relating to the use of LIBDEF and ISPF APPLIDs.           
  883.                                                                                 
  884.  It is in the GOPHER exec that you will also customize the name of the          
  885.  default Gopher server.  Note that the user's GOPHERRC file gets built          
  886.  from the contents of this exec.                                                
  887.                                                                                 
  888.  Note that if you install one of the REXX execs, you must also install          
  889.  the NNMFIUCV exec in the same library.  This exec implements a rude            
  890.  check for an existing TCP/IP socket application (e.g. another GOPHER)          
  891.  in a different PIE MultiTSO session.  It prevents your users from              
  892.  crashing TCP/IP, so it is highly recommended that you make use of it.          
  893.                                                                                 
  894.  4. If you are running ISPF Version 2 or earlier, edit the GOPHER panels        
  895.  whose names begin "GGMP...".  These are popups, and will not work              
  896.  under ISPF Version 2 unless you change the )BODY line.  Remove the             
  897.  WINDOW(...) parameter from the )BODY line of each panel so that the            
  898.  line just says )BODY or )BODY EXPAND(``), as the case may be.                  
  899.                                                                                 
  900.  Now, to install:                                                               
  901.                                                                                 
  902.  5. Submit the ALLOAD JCL to allocate the load library from which the           
  903.  executable program will be run.  If you intend to place the executable         
  904.  into an existing library, you can skip this step, but you should make          
  905.  sure that there is no previous load module named GGCLIENT in the load          
  906.  library of your choice before you proceed.                                     
  907.                                                                                 
  908.  6. Submit the COMPILEC JCL to compile all the C sources and create             
  909.  the executable Gopher load module.                                             
  910.                                                                                 
  911.  The first time you run this you can expect a return code of 8 from             
  912.  the linkedit.  Like SMP/E, this is OK if the only reason is an IEW0342         
  913.  because the "INCLUDE SYSLMOD(GGCLIENT)" did not find an existing load          
  914.  module.  If you get IEW0132 (unresolved external reference) or                 
  915.  IEW0241 (ESD type definition conflict), your linkedit went awry.               
  916.  Don't use the resultant load module.  Check the libraries you                  
  917.  specified on the link step to see what went wrong.                             
  918.                                                                                 
  919.  In the future, if you have to recompile individual modules, you can use        
  920.  the same JCL to compile only those modules, and the link will include          
  921.  the new modules in the existing executable load module.                        
  922.                                                                                 
  923.  *********************************************************************          
  924.                                                                                 
  925.  IMPORTANT:  If you are running TCP/IP V2R2 or higher on MVS, you must          
  926.  change the following library names in the compile and link JCL:                
  927.                                                                                 
  928.    TCPIP.COMMMAC   should be changed to  TCPIP.SEZACMAC                         
  929.    TCPIP.COMMTXT   should be changed to  TCPIP.SEZACMTX                         
  930.                                                                                 
  931.  If you are using SNS/TCPAccess, use these library names, or                    
  932.  whatever names are defined at your installation:                               
  933.                                                                                 
  934.    TCPIP.COMMMAC   should be changed to  SNSTCP.V110.H                          
  935.    TCPIP.COMMTXT   should be changed to  SNSTCP.V110.CILIB                      
  936.                                                                                 
  937.  *********************************************************************          
  938.                                                                                 
  939.  Note:  If you have defined C370V1 in the GGUSER header file, you must          
  940.  also include the system linklist load library or libraries containing          
  941.  ISPLINK, ISPEXEC and IKJEFF18 when linking.  Otherwise you may delete          
  942.  the lines from the linkedit JCL that reference them.                           
  943.                                                                                 
  944.  Note:  You need not include the PASCAL libraries or the AMPZMVSB               
  945.  module if you are using TCP/IP Version 2 or higher, in which case              
  946.  you must also define TCPIPV2 in the GGUSER headerfile.                         
  947.                                                                                 
  948.  7. Copy all the members of the panel PDS into the ISPF panel library           
  949.  specified in the GOPHER exec.                                                  
  950.                                                                                 
  951.  8. Copy one of the help members (HELP or HELQ) from the CNTL PDS into          
  952.  your local TSO HELP library under the name GOPHER.  You may also               
  953.  create an additional HELP member called GOPHLOC containing                     
  954.  information local to your site, if you wish.                                   
  955.                                                                                 
  956.  Which CNTL member should you use?  If you don't have XPROC, use HELQ.          
  957.  If you do have XPROC, use HELP.  You will have to modify your GOPHER           
  958.  clist either way.  If you don't have XPROC, you should get it,                 
  959.  because you can specify more options on Gopher if you do.  You can             
  960.  get XPROC via USC's "MVS network server" code distribution service.            
  961.  For more information about this, send an email message to                      
  962.  SERVICE@MVSA.USC.EDU - or SERVICE@USCMVSA, which will normally give            
  963.  better results if you have a BITNET (NJE) return address.                      
  964.                                                                                 
  965.  9. Create the "About This Gopher" PDS from the ABOUT PDS.  This has            
  966.  all the text users should see when they select the "About This Gopher"         
  967.  item from the MVS client.  It also contains all the documentation you          
  968.  need about setting up the client and the server, as well as creating           
  969.  menus and REXX execs for use with MVS Gopher.  You may have already            
  970.  done this as part of the server install, but it should also be                 
  971.  available from the client in "local" (serverless) mode, so that is             
  972.  why I mention it here.                                                         
  973.                                                                                 
  974. --------------------------------------------------------------------            
  975.                                                                                 
  976.  Note:  Make sure that the C/370 run time library is available,                 
  977.  either in the system link list or in the ISPLLIB concatenation,                
  978.  before attempting to run GOPHER.                                               
  979.                                                                                 
  980.  If the C/370 runtime library is not in the link list or otherwise              
  981.  available to ISPF at execution time, you may arrange for it to be              
  982.  allocated via LIBDEF in the GOPHER exec (I haven't tried this).                
  983.                                                                                 
  984. ./   ADD NAME=INSTALLS,SSI=010B0042                                             
  985.                                                                                 
  986.  Directions for Installing the GOPHER MVS Server                                
  987.                                                                                 
  988.  Assuming the PDS's have been created:                                          
  989.                                                                                 
  990.  1. Customize the ALLOAD and COMPILES JCL members to reflect your               
  991.  local conventions.  Note:  If you intend to place the executable into          
  992.  an existing library, you can suppress that part of the ALLOAD JCL.             
  993.  The name of the data set created must match across both members.               
  994.                                                                                 
  995.  2. Customize the GGUSER header file as shown by the comments therein.          
  996.  Note in particular the defines for your TCP/IP and your C compiler.            
  997.  There are changes to the linkedit JCL that are related to these.               
  998.                                                                                 
  999.  Now, to install:                                                               
  1000.                                                                                 
  1001.  3. Submit the ALLOAD JCL to allocate the load library from which the           
  1002.  executable program will be run.  If you intend to place the executable         
  1003.  into an existing library, you can skip this step, but you should make          
  1004.  sure that there is no previous load module named GGSERVER or GGSTASK           
  1005.  in the load library of your choice before you proceed.                         
  1006.                                                                                 
  1007.  4. Submit the COMPILES JCL to compile all the C sources and create             
  1008.  the executable Gopher load modules.                                            
  1009.                                                                                 
  1010.  The first time you run this you can expect return codes of 8 from              
  1011.  the linkedit.  Like SMP/E, this is OK if the only reason is an IEW0342         
  1012.  because the "INCLUDE SYSLMOD(...)" did not find an existing load               
  1013.  module.  If you get IEW0132 (unresolved external reference) or                 
  1014.  IEW0241 (ESD type definition conflict), your linkedit went awry.               
  1015.  Don't use the resultant load module.  Check the libraries you                  
  1016.  specified on the link step to see what went wrong.                             
  1017.                                                                                 
  1018.  In the future, if you have to recompile individual modules, you can use        
  1019.  the same JCL to compile only those modules, and the link will include          
  1020.  the new modules in the existing executable load module.                        
  1021.                                                                                 
  1022.  *********************************************************************          
  1023.                                                                                 
  1024.  IMPORTANT:  If you are running TCP/IP V2R2 or higher on MVS, you must          
  1025.  change the following library names in the compile and link JCL:                
  1026.                                                                                 
  1027.    TCPIP.COMMMAC   should be changed to  TCPIP.SEZACMAC                         
  1028.    TCPIP.COMMTXT   should be changed to  TCPIP.SEZACMTX                         
  1029.                                                                                 
  1030.  If you are using SNS/TCPAccess, use these library names, or                    
  1031.  whatever names are defined at your installation:                               
  1032.                                                                                 
  1033.    TCPIP.COMMMAC   should be changed to  SNSTCP.V110.H                          
  1034.    TCPIP.COMMTXT   should be changed to  SNSTCP.V110.CILIB                      
  1035.                                                                                 
  1036.  *********************************************************************          
  1037.                                                                                 
  1038.  Note:  If you have defined C370V1 in the GGUSER header file, you must          
  1039.  also include the system linklist load library containing IKJEFF18              
  1040.  when linking.  Otherwise you may delete the line from the linkedit             
  1041.  JCL that references it.                                                        
  1042.                                                                                 
  1043.  Note:  You need not include the PASCAL libraries or the AMPZMVSB               
  1044.  module if you are using TCP/IP Version 2 or higher, in which case              
  1045.  you must also define TCPIPV2 in the GGUSER headerfile.                         
  1046.                                                                                 
  1047.  5. Create the "About This Gopher" PDS from the ABOUT PDS.  This has            
  1048.  all the text users should see when they select the "About This Gopher"         
  1049.  item from the MVS client.  It also contains all the documentation you          
  1050.  need about setting up the client and the server, as well as creating           
  1051.  menus and REXX execs for use with MVS Gopher.  You may have already            
  1052.  done this as part of the client install.                                       
  1053.                                                                                 
  1054.  *** NOTE: In member MENU, you must change the line that reads                  
  1055.  "PATH=GOPHER.ABOUT.PDS(ABOUT)" to reflect the actual name of your              
  1056.  ABOUT PDS.  If you are using an earlier distribution of the MVS                
  1057.  Gopher server that has the line PATH=DD:GGABOUT(ABOUT), then you               
  1058.  must change that as well, because that won't work to get additional            
  1059.  PDS members as the user climbs down the Gopher tree.                           
  1060.                                                                                 
  1061.  6. Create your Gopher access file.  See the instructions in the                
  1062.  "About This Gopher" PDS for the format.                                        
  1063.                                                                                 
  1064.  7. Create your Gopher startup parameter file.  This is not required,           
  1065.  but may be used to change compiled-in defaults.  See the PARMS member          
  1066.  for a default.                                                                 
  1067.                                                                                 
  1068.  8. Allocate a PDS to hold Gopher REXX execs.  This is not required.            
  1069.  See the TSOHELP exec in the clist library of the distribution for a            
  1070.  sample application.                                                            
  1071.                                                                                 
  1072.  9. Create the MVS Gopher started task JCL from either of the samples           
  1073.  given in GOPHERD and GOPHERT.  The GOPHERT is recommended so that you          
  1074.  can use REXX execs that issue TSO commands, but you may not want to            
  1075.  use this for security reasons.  Either way, customize liberally.               
  1076.                                                                                 
  1077.  Started task parameters:                                                       
  1078.                                                                                 
  1079.  MODULE=GGSERVER            the Gopher server load module in STEPLIB            
  1080.  STEPLIB='GOPHER.LOAD'      the load library containing the above               
  1081.  EXECLIB='GOPHER.EXEC'      the PDS containing server REXX execs                
  1082.  ACCESS='GOPHER.ACCESS'     the installation access file (sequential)           
  1083.  ABOUT='GOPHER.ABOUT'       the PDS containing "About This Gopher" info         
  1084.  MENU='GOPHER.MENU'         the initial gopher menu (sequential)                
  1085.  PARMS='GOPHER.PARMS'       the server startup file (sequential)                
  1086.  GPARM=                     the server EXEC parms (e.g. -d for debug)           
  1087.                                                                                 
  1088.  Note: if you specify GPARM='-D', a GGDEBUG DD must be included.                
  1089.                                                                                 
  1090.  You are strongly recommended to create 2 started tasks:  one for               
  1091.  non-REXX requests with MTFTASKS set to 8, and one for REXX requests            
  1092.  with MTFTASKS set to 1 (because of TSO/E multitasking bugs).                   
  1093.  Give each a different port number in the GGPARMS configuration file            
  1094.  allocated to it.  See sample below.                                            
  1095.                                                                                 
  1096.  10. Add the name of the Gopher server started task (the name as it             
  1097.  appears in SYS1.PROCLIB, not necessarily "GOPHER") to the MVS TCPIP            
  1098.  profile data set (or have your MVS TCP/IP system programmer do it).            
  1099.  In the examples below, let's say you've called it GOPHSRV.  Add this           
  1100.  in 2 places:                                                                   
  1101.                                                                                 
  1102.    (a) under AUTOLOG, so that TCP/IP will start the Gopher server               
  1103.        automatically (a la inetd for unix) when a client connects.              
  1104.        Just add the name to the list (e.g. GOPHSRV).                            
  1105.                                                                                 
  1106.    (b) under PORT, so nobody can spoof the Gopher port.  The format             
  1107.        here is:   70 TCP GOPHSRV                                                
  1108.                                                                                 
  1109.  Repeat both for whatever number of Gopher server started tasks you             
  1110.  create (with different port numbers).                                          
  1111.                                                                                 
  1112. --------------------------------------------------------------------            
  1113.                                                                                 
  1114.  Note:  Make sure that the C/370 run time library is available,                 
  1115.  either in the system link list or in the STEPLIB concatenation,                
  1116.  before attempting to run GOPHER.                                               
  1117.                                                                                 
  1118. --------------------------------------------------------------------            
  1119.                                                                                 
  1120. Following is an example of how to define two Gopher servers.                    
  1121.                                                                                 
  1122. 'SYS1.PROCLIB(GOPHSRV)' - the primary gopher server (port 70)                   
  1123.                           will not run any REXX execs                           
  1124.                                                                                 
  1125. //GOPHERD  PROC MODULE=GGSERVER,                                                
  1126. //         STEPLIB='GOPHER.LOAD',                                               
  1127. //         ACCESS='GOPHER.ACCESS(ACCESS)',                                      
  1128. //         PARMS='GOPHER.ACCESS(PARMS)',                                        
  1129. //         MENU='GOPHER.ACCESS(MENU)',                                          
  1130. //         STDERR='*',                                                          
  1131. //         STDOUT='*',                                                          
  1132. //         GPARM=                                                               
  1133. //*                                                                             
  1134. //GOPHERD  EXEC PGM=&MODULE,PARM='&GPARM'                                       
  1135. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                           
  1136. //SYSERR   DD   SYSOUT=&STDERR                                                  
  1137. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  1138. //SYSIN    DD   DUMMY                                                           
  1139. //GGDEBUG  DD   SYSOUT=*                                                        
  1140. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                            
  1141. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  1142. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                              
  1143.                                                                                 
  1144. 'SYS1.PROCLIB(GOPHSRV2)' - the secondary gopher server (port 1570)              
  1145.                            will run REXX execs                                  
  1146.                                                                                 
  1147. //GOPHERD2 PROC MODULE=GGSERVER,                                                
  1148. //         STEPLIB='GOPHER.LOAD',                                               
  1149. //         EXECLIB='GOPHER.EXEC',                                               
  1150. //         ACCESS='GOPHER.ACCESS(ACCESS2)',                                     
  1151. //         PARMS='GOPHER.ACCESS(PARMS2)',                                       
  1152. //         MENU='GOPHER.ACCESS(MENU2)',                                         
  1153. //         VIO=VIO,                                                             
  1154. //         STDERR='*',                                                          
  1155. //         STDOUT='*',                                                          
  1156. //         GPARM=                                                               
  1157. //*                                                                             
  1158. //GOPHERD2 EXEC PGM=IKJEFT01,DYNAMNBR=128, PARM='&MODULE &GPARM'                
  1159. //STEPLIB  DD   DISP=SHR,DSN=&STEPLIB                                           
  1160. //SYSEXEC  DD   DISP=SHR,DSN=&EXECLIB  /* needed for %-invoked execs */         
  1161. //GGEXEC   DD   DISP=SHR,DSN=&EXECLIB                                           
  1162. //SYSTSPRT DD   UNIT=&VIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255             
  1163. //SYSERR   DD   SYSOUT=&STDERR                                                  
  1164. //SYSPRINT DD   SYSOUT=&STDOUT                                                  
  1165. //SYSTSIN  DD   DUMMY                                                           
  1166. //SYSIN    DD   DUMMY                                                           
  1167. //GGDEBUG  DD   SYSOUT=*                                                        
  1168. //GGACCESS DD   DISP=SHR,DSN=&ACCESS                                            
  1169. //GGPARMS  DD   DISP=SHR,DSN=&PARMS                                             
  1170. //GGGOPHER DD   DISP=SHR,DSN=&MENU                                              
  1171.                                                                                 
  1172. 'GOPHER.ACCESS(PARMS)' - startup parameters used by the primary server          
  1173.                                                                                 
  1174. mtftasks  8    (this is the default)                                            
  1175. port      70   (this is the default too)                                        
  1176.                                                                                 
  1177. 'GOPHER.ACCESS(PARMS2)'- startup parameters used by the secondary server        
  1178.                                                                                 
  1179. mtftasks  1       Force single threading to prevent TSO burpages                
  1180. port      1570    Must be different from primary server's port                  
  1181.                                                                                 
  1182. -----------------------------------------------------------------------         
  1183.                                                                                 
  1184. I have not included members ACCESS, ACCESS2, MENU and MENU2, but you            
  1185. will find samples elsewhere in this distribution.  ACCESS and ACCESS2           
  1186. can be the same, except that you don't need the REXX execs to be in             
  1187. ACCESS since ACCESS can't run REXX execs.  MENU and MENU2 should be             
  1188. the same, since you may want to configure various Gopher clients                
  1189. on other machines to try both MVS servers, but it's up to you.                  
  1190.                                                                                 
  1191. ./   ADD NAME=MENU,SSI=01030021                                                 
  1192. gopher_menu                                                                     
  1193.                                                                                 
  1194. TYPE=FILE                                                                       
  1195. NAME=About This Gopher                                                          
  1196. PATH=GOPHER.ABOUT.PDS(ABOUT)                                                    
  1197. HOST=+                                                                          
  1198. END                                                                             
  1199.                                                                                 
  1200. TYPE=FILE                                                                       
  1201. NAME=TSO HELP (Sample Illustrating the REXX Interface)                          
  1202. PATH=EXEC:TSOHELP                                                               
  1203. HOST=+                                                                          
  1204. END                                                                             
  1205.                                                                                 
  1206. TYPE=DIRECTORY                                                                  
  1207. NAME=Library/Information Services                                               
  1208. PATH=SYS0008.GOPHER.LIBRARY(LIBRS)                                              
  1209. HOST=MVS.UDEL.EDU                                                               
  1210. END                                                                             
  1211.                                                                                 
  1212. TYPE=TELNET                                                                     
  1213. NAME=UDINFO - University of Delaware Information                                
  1214. HOST=UDINFO.UDEL.EDU                                                            
  1215. END                                                                             
  1216.                                                                                 
  1217. TYPE=DIRECTORY                                                                  
  1218. NAME=Network and System Services Computer Systems                               
  1219. PATH=SYS0008.GOPHER.DIR(UDTELNET)                                               
  1220. HOST=MVS.UDEL.EDU                                                               
  1221. END                                                                             
  1222.                                                                                 
  1223. TYPE=DIRECTORY                                                                  
  1224. NAME=Weather Across the Country                                                 
  1225. PATH=1/Weather                                                                  
  1226. HOST=mermaid.micro.umn.edu                                                      
  1227. PORT=150                                                                        
  1228. END                                                                             
  1229.                                                                                 
  1230. TYPE=DIRECTORY                                                                  
  1231. NAME=Other Gopher and Information Servers                                       
  1232. PATH=1/Other Gopher and Information Servers                                     
  1233. HOST=gopher.micro.umn.edu                                                       
  1234. END                                                                             
  1235.                                                                                 
  1236. TYPE=DIRECTORY                                                                  
  1237. NAME=How to use BITNET LISTSERV Servers                                         
  1238. PATH=SYS0008.GOPHER.DIR(LISTSERV)                                               
  1239. HOST=MVS.UDEL.EDU                                                               
  1240. END                                                                             
  1241.                                                                                 
  1242. TYPE=DIRECTORY                                                                  
  1243. NAME=University of Delaware Newspapers                                          
  1244. PATH=SYS0008.GOPHER.DIR(PAPERS)                                                 
  1245. HOST=MVS.UDEL.EDU                                                               
  1246. END                                                                             
  1247.                                                                                 
  1248. /*                                                                              
  1249. ./   ADD NAME=PARMS,SSI=01000028                                                
  1250. !                                                                               
  1251. ! MVS Gopher Sample Startup Parameter File                                      
  1252. !                                                                               
  1253. ! All entries in this file have the format:   variable value comments           
  1254. !                                                                               
  1255. ! These are the possible values and their default settings:                     
  1256. !                                                                               
  1257. ! mtftasks 1    Number of concurrent subtasks to handle client requests         
  1258. ! port     70   The TCP port number by which clients connect                    
  1259. ! qlength  20   Queue length for TCP server listen function                     
  1260. ! timeout  60   Connection timeout specified when socket is closed              
  1261. ! domain   .DRAPER.COM     The suffix to be appende to bald host names          
  1262.                                                                                 
  1263. mtftasks 1    Number of concurrent subtasks to handle client requests           
  1264. port     70   The TCP port number by which clients connect                      
  1265. qlength  20   Queue length for TCP subtask creation                             
  1266. timeout  60   Connection timeout specified when socket is closed                
  1267.                                                                                 
  1268. ./ ENDUP                                                                        
  1269. ?!                                                                              
  1270. //ABOUT    EXEC GGLOAD,TRK1='6',TO='ABOUT'                                      
  1271. //SYSIN    DD DATA,DLM='?!'                                                     
  1272. ./   ADD NAME=ABOUT,SSI=01040045                                                
  1273. gopher_menu                                                                     
  1274.                                                                                 
  1275. TYPE=FILE                                                                       
  1276. NAME=What Is Gopher?                                                            
  1277. PATH=(ABOUTW)                                                                   
  1278. HOST=+                                                                          
  1279. END                                                                             
  1280.                                                                                 
  1281. TYPE=FILE                                                                       
  1282. NAME=Gopher FAQ (Frequently Asked Questions) List                               
  1283. PATH=(FAQ)                                                                      
  1284. HOST=+                                                                          
  1285. END                                                                             
  1286.                                                                                 
  1287. TYPE=DIRECTORY                                                                  
  1288. NAME=Using The Gopher MVS Client                                                
  1289. PATH=(ABOUTC)                                                                   
  1290. HOST=+                                                                          
  1291. END                                                                             
  1292.                                                                                 
  1293. TYPE=DIRECTORY                                                                  
  1294. NAME=Administering the Gopher MVS Server                                        
  1295. PATH=(ABOUTS)                                                                   
  1296. HOST=+                                                                          
  1297. END                                                                             
  1298.                                                                                 
  1299.                                                                                 
  1300. ./   ADD NAME=ABOUTC,SSI=01050028                                               
  1301. gopher_menu                                                                     
  1302.                                                                                 
  1303. TYPE=FILE                                                                       
  1304. NAME=Overview - Using Gopher on MVS                                             
  1305. PATH=(ABOUTCO)                                                                  
  1306. HOST=+                                                                          
  1307. END                                                                             
  1308.                                                                                 
  1309. TYPE=FILE                                                                       
  1310. NAME=Directory Mode - Viewing a Gopher Directory                                
  1311. PATH=(ABOUTCD)                                                                  
  1312. HOST=+                                                                          
  1313. END                                                                             
  1314.                                                                                 
  1315. TYPE=FILE                                                                       
  1316. NAME=File Mode - Browsing a Gopher File                                         
  1317. PATH=(ABOUTCF)                                                                  
  1318. HOST=+                                                                          
  1319. END                                                                             
  1320.                                                                                 
  1321. TYPE=FILE                                                                       
  1322. NAME=Index Mode - Executing a Gopher Query                                      
  1323. PATH=(ABOUTCQ)                                                                  
  1324. HOST=+                                                                          
  1325. END                                                                             
  1326.                                                                                 
  1327. TYPE=DIRECTORY                                                                  
  1328. NAME=Customizing Your Gopher Startup                                            
  1329. PATH=(ABOUTCS)                                                                  
  1330. HOST=+                                                                          
  1331. END                                                                             
  1332.                                                                                 
  1333.                                                                                 
  1334. ./   ADD NAME=ABOUTCD,SSI=01030050                                              
  1335. Directory Mode - Viewing a Gopher Directory                                     
  1336.                                                                                 
  1337. When you are viewing a Gopher directory, you may perform any of the             
  1338. following actions:                                                              
  1339.                                                                                 
  1340.  * Scroll up and down via the normal ISPF UP and DOWN commands or PFK's         
  1341.                                                                                 
  1342.  * Type one of the following letters to the left of a menu item:                
  1343.                                                                                 
  1344.    S - Select the item for viewing or processing                                
  1345.    E - Extract the contents of the item to a file                               
  1346.    P - Print the contents of the item to a system printer                       
  1347.    B - Save the entry as a bookmark (in a bookmark file)                        
  1348.    D - Delete this entry from the bookmark file *** not yet supported **        
  1349.    Q - Display the item as a file, even if it isn't ("Query")                   
  1350.    I - Display the internal Information of the menu item                        
  1351.                                                                                 
  1352.  * Enter one of the following commands on the command line:                     
  1353.                                                                                 
  1354.    MENU - load a data set containing Gopher menu entries (e.g. bookmark)        
  1355.    OPTions - set client processing options                                      
  1356.    QUIT - exit Gopher entirely                                                  
  1357.                                                                                 
  1358.    or any standard ISPF command.                                                
  1359.                                                                                 
  1360. Note:  Currently, in order to use the E or P selection code, you must           
  1361.        choose the item via S or Q first.                                        
  1362.                                                                                 
  1363. When you select an item, what happens next depends on the type of the           
  1364. item you have selected.                                                         
  1365.                                                                                 
  1366. For a File type, you are placed in browse mode on the data.                     
  1367.                                                                                 
  1368. For a Directory type, you get another Gopher directory.                         
  1369.                                                                                 
  1370. For an Index type, you see a panel asking you to enter a search string          
  1371. of some kind, after which a Gopher directory of results appears.                
  1372.                                                                                 
  1373. For a TELNET type, a telnet session is started, for which you must              
  1374. enter a login name at the appropriate time.                                     
  1375.                                                                                 
  1376. For a TN3270 type, a tn3270 session is started, for which you must              
  1377. enter a login name at the appropriate time.                                     
  1378.                                                                                 
  1379. For a CSO type, you are placed in a phonebook lookup session.                   
  1380.                                                                                 
  1381. ./   ADD NAME=ABOUTCF,SSI=01030024                                              
  1382. Browse Mode - Viewing a File in Gopher                                          
  1383.                                                                                 
  1384. When you are viewing a Gopher file, you are placed in "browse mode".            
  1385. This is very similar to normal ISPF data set browse, except that:               
  1386.                                                                                 
  1387.  * In addition to most browse commands, you may issue any of the                
  1388.    following commands:                                                          
  1389.                                                                                 
  1390.    EXT or EXTRACT   - copy the current contents to a file                       
  1391.    PRT or PRNT      - print the current data to SYSOUT.                         
  1392.    BOOK or BOOKMARK - Save the entry as a bookmark (in a bookmark file).        
  1393.    INFO             - Display the internal Information for this item            
  1394.    OPTions          - Set Gopher client processing options                      
  1395.    QUIT - terminates Gopher entirely.                                           
  1396.                                                                                 
  1397.    Note that PRT is different from PRINT, which is a built-in ISPF              
  1398.    command that prints the current physical screen image.                       
  1399.                                                                                 
  1400.  * The following ISPF browse commands are the only ones that are                
  1401.    ***not*** supported under GOPHER:                                            
  1402.                                                                                 
  1403.   HEX                                                                           
  1404.   BROWSE                                                                        
  1405.   SUBMIT                                                                        
  1406.   LOCATE .label                                                                 
  1407.   .<string> (to assign a label)                                                 
  1408.   FIND P'generic-string'                                                        
  1409.   DISPLAY CC/NOCC                                                               
  1410.                                                                                 
  1411. ./   ADD NAME=ABOUTCO,SSI=01010039                                              
  1412. The following is modified from Allan Tuchman's XGOPHER help.                    
  1413.                                                                                 
  1414. Gopher on MVS is an ISPF dialog interface to the Gopher                         
  1415. information delivery system from the University of Minnesota.                   
  1416.                                                                                 
  1417. The initial panel asks you to specify the name of the Gopher server             
  1418. host.  Normally you leave the other input fields alone.                         
  1419.                                                                                 
  1420. You may also specify a hostname of "-", which means that you want               
  1421. to use your own private Gopher data without going through a server.             
  1422. When you do this, you must provide the path name to your private                
  1423. top-level menu (data set name, FULLY QUALIFIED, WITHOUT QUOTES).                
  1424.                                                                                 
  1425. Assuming that the top-level path points to a valid Gopher menu,                 
  1426. the initial display will show the top level directory of                        
  1427. gopher information available.  Selecting an item from this                      
  1428. list will fetch the contents of a file, subdirectory, or                        
  1429. other information.  The directory display may be updated to                     
  1430. show the new subdirectory.                                                      
  1431.                                                                                 
  1432. To select an item, type "S" in front of it and press ENTER.                     
  1433. This puts you into ISPF BROWSE mode on the text of the item.                    
  1434. You may also type "Q" in front of an item to see it in text format              
  1435. even if it is a directory.  If you have retrieved an item, you may              
  1436. type "E" in front of it to extract it into a file - but you may                 
  1437. do this more easily via the EXTract command from within BROWSE.                 
  1438.                                                                                 
  1439. Type "I" in front of the item to view the internal menu information.            
  1440. This is sometimes helpful if you are not sure why you are having                
  1441. trouble accessing an item.                                                      
  1442.                                                                                 
  1443. Type "B" in front of the item to save it in a bookmark file.  You will          
  1444. be prompted to supply the name of a bookmark data set; the default is           
  1445. GOPHER.BOOKMARK under your TSO prefix.  You may retrieve bookmarks at a         
  1446. later date by typing "MENU GOPHER.BOOKMARK" - or whatever data set name         
  1447. you used - or you can put a pointer to the bookmark data set in your            
  1448. private Gopher menu (for which you need to learn how to hack your               
  1449. GOPHERRC file).                                                                 
  1450.                                                                                 
  1451. Some gopher file types are not supported by the current client.                 
  1452. These will not appear on your menus.  Furthermore, you may not                  
  1453. be permitted to access some items, depending upon the server                    
  1454. and the host from which you are trying to access them.  These                   
  1455. restrictions do not apply to local mode, where you can access                   
  1456. anything that you have local permission to read.                                
  1457.                                                                                 
  1458. The Gopher MVS client is written by Steve Bacher at Draper Laboratory           
  1459. (copyright 1992).                                                               
  1460.                                                                                 
  1461. ./   ADD NAME=ABOUTCQ,SSI=01020042                                              
  1462. Index Mode - Executing a Gopher Query                                           
  1463.                                                                                 
  1464. When you select a Gopher "index" or "query" option, you are expected            
  1465. to enter some sort of search string.  A typical application is a                
  1466. phone book lookup, or a keyword search of some archive.                         
  1467.                                                                                 
  1468. You will see a popup panel (or just a plain panel if you are running            
  1469. an old version of ISPF) that asks you to enter a search string.  Just           
  1470. type it in and press ENTER.  What format the string needs to be in              
  1471. depends totally on the service that is going to process it.                     
  1472.                                                                                 
  1473. What you get back is a directory with a list of "hits" or whatever              
  1474. is appropriate for the data you requested.  This is just like any               
  1475. other Gopher directory.                                                         
  1476.                                                                                 
  1477. With the original Gopher protocol, there was no mechanism for                   
  1478. defining an index/query that returned file data immediately.                    
  1479. MVS Gopher supports an experimental "whois" type that does this.                
  1480. However, since it was only spottily implemented by other Gophers,               
  1481. and not always the right way (in the humble opinion of the author               
  1482. or the MVS client), it is not likely that you will see such an option           
  1483. on your Gopher screen.                                                          
  1484.                                                                                 
  1485. ./   ADD NAME=ABOUTCS,SSI=01030002                                              
  1486. gopher_menu                                                                     
  1487.                                                                                 
  1488. Type=FILE                                                                       
  1489. Name=Customizing Your Gopher Startup                                            
  1490. Path=(ABOUTCSC)                                                                 
  1491. Host=+                                                                          
  1492. End                                                                             
  1493.                                                                                 
  1494. Type=FILE                                                                       
  1495. Name=What Happens When You Start Up Gopher                                      
  1496. Path=(ABOUTCSW)                                                                 
  1497. Host=+                                                                          
  1498. End                                                                             
  1499.                                                                                 
  1500. Type=FILE                                                                       
  1501. Name=Requesting Local (Serverless) Access                                       
  1502. Path=(ABOUTCSL)                                                                 
  1503. Host=+                                                                          
  1504. End                                                                             
  1505.                                                                                 
  1506. Type=FILE                                                                       
  1507. Name=The GOPHERRC File                                                          
  1508. Path=(ABOUTCSR)                                                                 
  1509. Host=+                                                                          
  1510. End                                                                             
  1511.                                                                                 
  1512. Type=FILE                                                                       
  1513. Name=Defining GOPHER Menus                                                      
  1514. Path=(ABOUTCSM)                                                                 
  1515. Host=+                                                                          
  1516. End                                                                             
  1517.                                                                                 
  1518. Type=FILE                                                                       
  1519. Name=REXX Exec Interface                                                        
  1520. Path=(ABOUTCSX)                                                                 
  1521. Host=+                                                                          
  1522. End                                                                             
  1523.                                                                                 
  1524. ./   ADD NAME=ABOUTCSC,SSI=01030041                                             
  1525.                                                                                 
  1526. =======================================================================         
  1527.                                                                                 
  1528.  Customizing Your Gopher Startup                                                
  1529.                                                                                 
  1530. =======================================================================         
  1531.                                                                                 
  1532.  When you use the GOPHER client, information about your use of GOPHER           
  1533.  is stored in a data set called GOPHERRC.  If you don't have one,               
  1534.  GOPHER will create it for you.                                                 
  1535.                                                                                 
  1536.  Your default startup menu will contain a single item pointing to a             
  1537.  GOPHER server on your MVS system, whether such a server is available           
  1538.  or not.  However, you can ask GOPHER to display a different startup            
  1539.  menu for you.  This startup menu may have entries for the GOPHER               
  1540.  server on the MVS system and one for your own private (local) data,            
  1541.  which the GOPHER client accesses without querying a server.                    
  1542.                                                                                 
  1543.  To get GOPHER to set up a different startup menu, you must edit the            
  1544.  GOPHERRC file.  Note that you may set up the GOPHER startup menu to            
  1545.  include a pointer to your local data - but you have to create that             
  1546.  local data in order to use it.                                                 
  1547.                                                                                 
  1548.  Editing the GOPHERRC file should be easy.  Just follow the                     
  1549.  instructions in the comments of the file itself.  For information              
  1550.  about the contents of GOPHERRC, see "The GOPHERRC File."                       
  1551.                                                                                 
  1552. ./   ADD NAME=ABOUTCSL,SSI=01000056                                             
  1553.                                                                                 
  1554. =======================================================================         
  1555.                                                                                 
  1556.  Requesting Local (Serverless) Access                                           
  1557.                                                                                 
  1558. =======================================================================         
  1559.                                                                                 
  1560.  The LOCAL operand on the GOPHER command is a convenient way of                 
  1561.  requesting "local" serverless mode.  Specify LOCAL on the GOPHER               
  1562.  command if you want to enter GOPHER in "serverless" mode - i.e.                
  1563.  start up with your private GOPHER menu.  Specifying LOCAL                      
  1564.  accomplishes two things:                                                       
  1565.                                                                                 
  1566.   (1) It sets the server to "-", meaning local access.  Therefore, you          
  1567.       must also provide a path, either via the PATH operand on the              
  1568.       GOPHER command or via a "localmenu:" spec in your GOPHERRC file,          
  1569.       so that GOPHER knows where to look for your private data.  The            
  1570.       path is a data set name, FULLY QUALIFIED WITHOUT QUOTES.                  
  1571.                                                                                 
  1572.   (2) It allows you to use GOPHER even if there are other TCP/IP socket         
  1573.       applications active elsewhere in your TSO session.  However, it           
  1574.       will not allow you to connect to any GOPHER servers, even if you          
  1575.       have a local menu item that points to one.                                
  1576.                                                                                 
  1577.  If you do not specify a server and there is no specification in                
  1578.  your GOPHERRC file for one, then GOPHER will display a startup                 
  1579.  ISPF panel asking you to specify a server name and, optionally,                
  1580.  a path name.  (Don't touch the port number!)                                   
  1581. ./   ADD NAME=ABOUTCSM,SSI=01040003                                             
  1582.                                                                                 
  1583. =======================================================================         
  1584.                                                                                 
  1585.  Defining Gopher Menus                                                          
  1586.                                                                                 
  1587. =======================================================================         
  1588.                                                                                 
  1589.  This is a description of how to define GOPHER menus that can be used           
  1590.  either for your own private data or by the GOPHER server administrator         
  1591.  on MVS to define publicly accessible data.                                     
  1592.                                                                                 
  1593.  Bear in mind that the menu may be used to specify data meaningful to           
  1594.  a server other than MVS.  Therefore, the descriptions here should be           
  1595.  interpreted in two ways:                                                       
  1596.                                                                                 
  1597.  (1) how to define MVS-resident information resources                           
  1598.                                                                                 
  1599.  (2) how to request information resources from other GOPHER servers             
  1600.                                                                                 
  1601. ------------------------------------------------------------------------        
  1602.                                                                                 
  1603.  How To Define MVS-Resident Information Resources                               
  1604.                                                                                 
  1605.  The Gopher server (and the Gopher client, in "local" mode) determines          
  1606.  how to return information to the client via menus.  These menus are            
  1607.  plain MVS data sets with a particular structure.                               
  1608.                                                                                 
  1609.  An MVS gopher menu is a sequential data set or PDS member with the             
  1610.  following format:                                                              
  1611.                                                                                 
  1612.  * the first line contains the string GOPHER_MENU                               
  1613.    (in upper, lower or mixed case)                                              
  1614.                                                                                 
  1615.  * the rest of the file contains blocks of information like this:               
  1616.                                                                                 
  1617.    TYPE=type                                                                    
  1618.    NAME=name                                                                    
  1619.    PATH=path                                                                    
  1620.    HOST=host                                                                    
  1621.    PORT=port                                                                    
  1622.    END                                                                          
  1623.                                                                                 
  1624.    For compatibility with earlier versions of the MVS Gopher server,            
  1625.    the following are also accepted:                                             
  1626.                                                                                 
  1627.    DISPLAY=      is equivalent to NAME=                                         
  1628.    SELECTOR=     is equivalent to PATH=                                         
  1629.                                                                                 
  1630.    Explanations                                                                 
  1631.                                                                                 
  1632.    TYPE=type                                                                    
  1633.                                                                                 
  1634.    The type of Gopher entity (FILE, DIRECTORY, INDEX, etc.).                    
  1635.    In other words, one of the following:                                        
  1636.                                                                                 
  1637.    FILE      - the item is an MVS data set with text to be displayed.           
  1638.                The path name is the file name or a REXX exec spec.              
  1639.    DIRECTORY - the item is another Gopher directory.                            
  1640.                The path name is the file name or a REXX exec spec.              
  1641.    INDEX     - the item is a full text search item, which means that            
  1642.                the client will query the user for a search string               
  1643.                which will be passed to the server along with the                
  1644.                pathname.  For the MVS server.  it only makes sense for          
  1645.                the pathname to be a REXX exec specification.  The path          
  1646.                and the user's string are given to the host, which               
  1647.                returns a menu of selections.  See also WHOIS.                   
  1648.    TELNET    - the item is a Telnet server.                                     
  1649.                The path name is ignored.  The port number should be             
  1650.                omitted or set to 0, unless an alternate TELNET port             
  1651.                is required by the server referenced by HOST.                    
  1652.    TN3270    - the item is a TN3270 server.  This is like TELNET                
  1653.                except that it takes you to a full-screen IBM mainframe          
  1654.                terminal session.                                                
  1655.    CSO       - the item is a CSO phonebook server.  This is a campus            
  1656.                information protocol that is not an Internet standard,           
  1657.                but may be available at some universities.                       
  1658.    WHOIS     - the item is a "whois" query.  This is similar to the             
  1659.                INDEX type, except that the server returns a file                
  1660.                rather than a menu.  This is not (yet) an official               
  1661.                part of the Gopher protocol, though it does appear in            
  1662.                certain (patched) versions of other implementations.             
  1663.                                                                                 
  1664.    NAME=name                                                                    
  1665.                                                                                 
  1666.    The descriptive string that will appear in the Gopher client's               
  1667.    display of menu selections for this item.  Make this as human as             
  1668.    possible.  Case is preserved.                                                
  1669.                                                                                 
  1670.    PATH=path                                                                    
  1671.                                                                                 
  1672.    The pathname to be passed to the Gopher server to retrieve the               
  1673.    item.  See below for a fuller description.                                   
  1674.                                                                                 
  1675.    HOST=host                                                                    
  1676.                                                                                 
  1677.    The name of the Gopher server host that will process the request.            
  1678.    See below for a fuller description.                                          
  1679.                                                                                 
  1680.    PORT=port                                                                    
  1681.                                                                                 
  1682.    The TCP/IP port to connect to.  For Gopher, this should always be            
  1683.    port 70 (except for a TELNET or TN3270 type, whose port defaults to          
  1684.    the standard TELNET port if zero or omitted).  If this is omitted,           
  1685.    then the default port number is taken.                                       
  1686.                                                                                 
  1687.    END                                                                          
  1688.                                                                                 
  1689.    Required to keep menu entries separate.                                      
  1690.                                                                                 
  1691.  Comment lines may be freely included, starting with '#' in                     
  1692.  the first column of data.                                                      
  1693.                                                                                 
  1694. More about Path Names                                                           
  1695.                                                                                 
  1696.  Note that the format of a path depends on which Gopher server is               
  1697.  going to be processing the entry, as defined by the HOST= field.               
  1698.  If the entry is going to a different Gopher server, then the                   
  1699.  pathname format depends on that server.  For example, a Unix server            
  1700.  would expect a Unix file name with a slash.                                    
  1701.                                                                                 
  1702.  A path name for the MVS Gopher may be one of the following:                    
  1703.                                                                                 
  1704.  * A fully qualified MVS data set name, without quotes, identifying             
  1705.    a sequential text data set or PDS member.  If TYPE=FILE, this is             
  1706.    text.  If TYPE=DIRECTORY, this is a gopher menu as described above.          
  1707.                                                                                 
  1708.  * A fully qualified MVS data set name, without quotes, identifying a           
  1709.    PDS (no member).  This causes the MVS Gopher server to return a              
  1710.    list of member names of the PDS in Gopher directory format.  This            
  1711.    is valid only with TYPE=DIRECTORY.  Member aliases are included in           
  1712.    the resulting list.                                                          
  1713.                                                                                 
  1714.  * A member name enclosed in parentheses.  This is treated as                   
  1715.    a full PDS member.  In other words, the MVS Gopher server will use           
  1716.    the name of the PDS in which the menu itself was found.                      
  1717.    This allows you to move PDS's full of Gopher menus around without            
  1718.    having to worry about changing all the path names.  This happens             
  1719.    only when the menu itself is a PDS member and the host is the                
  1720.    same as the local host (MVS for the server, - for local mode).               
  1721.    Specifying HOST=+ is recommended for this.                                   
  1722.                                                                                 
  1723.  * A string "DD:ddname" or "DD:ddname(member)", identifying a file by           
  1724.    MVS ddname a la C/370.  Valid with either TYPE=FILE or                       
  1725.    TYPE=DIRECTORY, so the ddname can point to text or a menu.                   
  1726.    However, if the ddname happens to be allocated to a PDS, it does             
  1727.    NOT work like a directory above - it's just illegal and will                 
  1728.    probably cause lossage.                                                      
  1729.                                                                                 
  1730.    Each member is treated as a Gopher FILE.  The NAME field is                  
  1731.    set to the member name.  If you want to do anything fancier                  
  1732.    than this, you will have to construct your own Gopher menu.                  
  1733.                                                                                 
  1734.  * A string "EXEC:execname args", which specifies the name of a                 
  1735.    REXX exec to be executed to return the data.  Valid with any                 
  1736.    and all types.  To learn more about how to make use of this                  
  1737.    feature, please go back to the "About This Gopher" tree and                  
  1738.    read up on using REXX execs with MVS Gopher.                                 
  1739.                                                                                 
  1740.    If you are using your own private GOPHER data via local access               
  1741.    and you want to run REXX execs, you must have a "localexec:"                 
  1742.    line in your GOPHERRC file identifying your REXX exec library.               
  1743.                                                                                 
  1744. More About Host Names                                                           
  1745.                                                                                 
  1746.  You may find that some Gopher servers insist on appending the                  
  1747.  network's domain name to local server hostnames.  You should check             
  1748.  with your network gurus to make sure that this will work with your             
  1749.  TCP/IP host lookup.  The MVS server will accept hostnames either               
  1750.  with or without the domain name appended - this applies to the                 
  1751.  specification of hostnames in the Gopher access table as well -                
  1752.  but other Gopher servers may not.                                              
  1753.                                                                                 
  1754. Two special cases:                                                              
  1755.                                                                                 
  1756.  A plus sign (HOST=+) means that the host is the same host as the one           
  1757.  that is looking at the directory entry - i.e. the server that is               
  1758.  serving up this menu.  The Gopher server simply plugs in its own host          
  1759.  name at that point.  This is NOT part of the Gopher protocol, but              
  1760.  merely a server hack.                                                          
  1761.                                                                                 
  1762.  A minus sign (HOST=-) means that access to this item will be in                
  1763.  "local" (serverless) mode.  This is recognized only by the MVS Gopher          
  1764.  client.  It means that the client will do the retrieval itself,                
  1765.  without asking a server to do it.                                              
  1766.                                                                                 
  1767.  The directory-processing code, when invoked in "local mode", will              
  1768.  treat HOST=+ as HOST=- since the current host is the local mode                
  1769.  operation in that case.  Therefore, using HOST=+ is recommended                
  1770.  so that one can port one's local GOPHER menus to the public server             
  1771.  at some point.                                                                 
  1772.                                                                                 
  1773.  A REXX exec that generates menus dynamically can use - as a hostname,          
  1774.  but not +.                                                                     
  1775.                                                                                 
  1776. ------------------------------------------------------------------------        
  1777.                                                                                 
  1778.  How To Request Information Resources From Other GOPHER Servers                 
  1779.                                                                                 
  1780. Rather than describe the standard format of a Gopher menu here,                 
  1781. I recommend that you go to your nearest Unix box and type                       
  1782.                                                                                 
  1783.   man gopherd                                                                   
  1784.                                                                                 
  1785. That should tell you all you need to know about Unix gopher servers.            
  1786. If your gopher server is on some other kind of machine, then go find            
  1787. the documentation for that machine's Gopher menus.                              
  1788.                                                                                 
  1789. The purpose of the above exercise is primarily to determine the format          
  1790. of a path name understood by a given Gopher server.  Once you know that,        
  1791. you can build a Gopher menu the MVS Gopher will understand, according to        
  1792. the format described in the top section.  Set the host to point to              
  1793. the other Gopher server, who will interpret the other items in the menu.        
  1794.                                                                                 
  1795. ------------------------------------------------------------------------        
  1796.                                                                                 
  1797. Dynamic Generation of GOPHER Menus                                              
  1798.                                                                                 
  1799.  If you want to be able to generate a Gopher menu dynamically,                  
  1800.  you can do this via the REXX interface.  You also must understand              
  1801.  the Gopher protocol.  A Gopher menu is really a text representation            
  1802.  of the actual protocol, which goes like this:                                  
  1803.                                                                                 
  1804.  filetype -tab- name -tab- path -tab- host -tab- port                           
  1805.                                                                                 
  1806.  where -tab- is the EBCDIC (on MVS) or ASCII (on other box) tab                 
  1807.  character, and filetype is a single character.  The filetypes                  
  1808.  supported by the MVS Gopher server are:                                        
  1809.                                                                                 
  1810.  0 - flat file                                                                  
  1811.  1 - directory                                                                  
  1812.  2 - CSO                                                                        
  1813.  3 - error                                                                      
  1814.  7 - index                                                                      
  1815.  8 - TELNET                                                                     
  1816.  T - TN3270                                                                     
  1817.  w - whois (experimental)                                                       
  1818.                                                                                 
  1819.  A REXX exec that wants to generate a Gopher menu must output lines             
  1820.  in this format.  For more information, go back to the Gopher tree              
  1821.  for "About This Gopher" and look up information on the REXX interface.         
  1822.                                                                                 
  1823. ./   ADD NAME=ABOUTCSR,SSI=01020018                                             
  1824.                                                                                 
  1825. =======================================================================         
  1826.                                                                                 
  1827.  The GOPHERRC File                                                              
  1828.                                                                                 
  1829. =======================================================================         
  1830.                                                                                 
  1831.  When you use the GOPHER client, you need a file called GOPHERRC                
  1832.  which stores information about your use of GOPHER.  If you don't               
  1833.  have one, GOPHER will create it for you.  The file initially                   
  1834.  contains:                                                                      
  1835.                                                                                 
  1836.     the initial path/name/host/port specification, which tells                  
  1837.     GOPHER what to display on startup.  By default this is the                  
  1838.     standard GOPHER server info on MVS.  However, you can add                   
  1839.     to your GOPHERRC a specification for local GOPHER by                        
  1840.     editing GOPHERRC and activating one of the following:                       
  1841.                                                                                 
  1842.     - the other "initial:" spec which points to your own startup menu,          
  1843.       overriding the one you'd get otherwise                                    
  1844.                                                                                 
  1845.     - the localmenu: and localexec: lines.                                      
  1846.                                                                                 
  1847.     localmenu: is equivalent to specifying an alternate initial:                
  1848.     spec of host=- (dash) and path=localmenu_name.  When you use                
  1849.     the LOCAL operand of the GOPHER command, localmenu: is what                 
  1850.     GOPHER looks for as the pathname if you don't provide one on                
  1851.     the command.                                                                
  1852.                                                                                 
  1853.     localexec: is required if you want to use your own library of               
  1854.     GOPHER rexx execs.  This is valid for LOCAL access only.                    
  1855.                                                                                 
  1856.     Some option defaults are stored in the GOPHERRC file.                       
  1857.     Note that this is not yet implemented.                                      
  1858.                                                                                 
  1859.     Note that bookmarks are not stored in your GOPHERRC file.                   
  1860.     They are stored in separate bookmark data sets, whose names                 
  1861.     the client user must specify.  Do not attempt to load your                  
  1862.     GOPHERRC file as a bookmark file!                                           
  1863.                                                                                 
  1864.     If you have a newly created GOPHERRC file, you can read the                 
  1865.     comments to guide you in customizing the file.                              
  1866. ./   ADD NAME=ABOUTCSW,SSI=01000034                                             
  1867.                                                                                 
  1868. =======================================================================         
  1869.                                                                                 
  1870.  What Happens When You Start Up GOPHER?                                         
  1871.                                                                                 
  1872. =======================================================================         
  1873.                                                                                 
  1874.  What you see when you start up GOPHER depends on what you have                 
  1875.  specified, either on the command line or in the GOPHERRC file.                 
  1876.  In general, command operands override GOPHERRC specifications.                 
  1877.                                                                                 
  1878.  GOPHER does its thing by connecting to a Gopher server somewhere               
  1879.  on your network.  If you do not specify otherwise, this server is              
  1880.  assumed to be MVS (the host where you are running this client).                
  1881.  The default GOPHERRC file specifies this as the server.                        
  1882.  The startup menu you see is the one defined by the administrator               
  1883.  of that server.                                                                
  1884.                                                                                 
  1885.  You can request a different server or a different startup menu,                
  1886.  either by modifying the GOPHERRC file or by specifying command                 
  1887.  operands.  The SERVER operand tells GOPHER to get a startup menu               
  1888.  from a different server, and the PATH operand tells GOPHER what                
  1889.  startup menu to request (the contents of the path depend on what               
  1890.  server you point to and what it's looking for, but it is typically             
  1891.  the name of a file on that system that contains a Gopher menu).                
  1892.                                                                                 
  1893.  You can also use GOPHER to access your own private data by requesting          
  1894.  "local" (serverless) mode.  A server name of a single dash "-" means           
  1895.  local access.  In this case, you must provide a path name so that              
  1896.  GOPHER knows where to look for your data.  The path name is the name           
  1897.  of a data set containing your GOPHER menu - it must be FULLY QUALIFIED         
  1898.  AND WITHOUT QUOTES.  The path name can be provided either as a command         
  1899.  operand or in the GOPHERRC file.                                               
  1900. ./   ADD NAME=ABOUTCSX,SSI=01040036                                             
  1901. =======================================================================         
  1902.                                                                                 
  1903. REXX Exec Interface                                                             
  1904.                                                                                 
  1905. =======================================================================         
  1906.                                                                                 
  1907. You can request the MVS Gopher server (or the MVS Gopher client, in             
  1908. "local" (serverless) mode) to retrieve information dynamically by               
  1909. executing a REXX exec.  To request this, you define a menu entry                
  1910. with the following PATH= field:                                                 
  1911.                                                                                 
  1912. PATH=EXEC:execname args                                                         
  1913.                                                                                 
  1914. In the case of EXEC:, the REXX exec identified by "execname" is                 
  1915. executed, along with the arguments "args" given.  For example:                  
  1916.                                                                                 
  1917. PATH=EXEC:MYEXEC ANY ARGS                                                       
  1918.                                                                                 
  1919. will cause the MYEXEC exec to be executed with "ANY ARGS" as the                
  1920. single argument string.                                                         
  1921.                                                                                 
  1922. If the TYPE is INDEX, the search string submitted by the user will be           
  1923. appended to the args separated by a blank.  The exec must be able to            
  1924. deal with this.                                                                 
  1925.                                                                                 
  1926. REXX Execs must be in a PDS allocated to DD GGEXEC.  This ddname                
  1927. needs to be allocated in the Gopher server's JCL.  For local mode,              
  1928. the GOPHER command will allocate the GGEXEC file to the REXX exec               
  1929. library specified on the "localexec:" line in your GOPHERRC file,               
  1930. if you have activated it.  Otherwise you will not be able to use                
  1931. REXX execs in local mode.                                                       
  1932.                                                                                 
  1933. Note that you do not need the /* REXX */ comment at the beginning of            
  1934. REXX execs used by gopher (though it does not hurt to include it!)              
  1935. because they are invoked by the IRXEXEC facility and not the standard           
  1936. TSO CLIST/EXEC search.                                                          
  1937.                                                                                 
  1938. Now, how does the REXX exec return data to the Gopher server?                   
  1939.                                                                                 
  1940. First of all, it depends on the TYPE that the exec is expected                  
  1941. to return, which has nothing to do with HOW the returning is done.              
  1942.                                                                                 
  1943. So, first let's talk about how the exec returns data, and then                  
  1944. about what it is expected to return.                                            
  1945.                                                                                 
  1946. How to return data                                                              
  1947.                                                                                 
  1948. The REXX exec must return data by writing it to the SYSTSPRT DD.                
  1949. Note that this is where normal TSO output goes when a REXX exec                 
  1950. is run in TSO batch.  However, since REXX execs are invoked by                  
  1951. the IRXEXEC interface by the Gopher server, to prevent dependency               
  1952. on a TSO environment, this default behavior of REXX/TSO cannot                  
  1953. be relied upon.  Therefore, if you write a REXX exec to return                  
  1954. Gopher data, you must explicitly send the output to the SYSTSPRT                
  1955. ddname.  The Gopher server makes sure that it can read this data.               
  1956.                                                                                 
  1957. A typical approach is to queue all the output to the REXX data stack,           
  1958. queue a final "" and then use EXECIO.  Be careful not to queue null             
  1959. lines in this case.  Be sure to protect the stack in case of lossage.           
  1960. Example:                                                                        
  1961.                                                                                 
  1962.  "NEWSTACK"                                                                     
  1963.  do while more_data_to_get                                                      
  1964.   some_data = get_some_data()                                                   
  1965.   if some_data = "" then queue " "                                              
  1966.   else queue some_data                                                          
  1967.  end                                                                            
  1968.  queue ""                                                                       
  1969.  "EXECIO * DISKW SYSTSPRT (FINIS)"                                              
  1970.  "DELSTACK"                                                                     
  1971.                                                                                 
  1972. You can also create a stem variable to hold the output, if you                  
  1973. want to avoid problems with null lines or nested stacks.  Example:              
  1974.                                                                                 
  1975.  do i = 1 to whatever                                                           
  1976.    foo.i = get_some_data()                                                      
  1977.  end                                                                            
  1978.  foo.0 = i                                                                      
  1979.  "EXECIO * DISKW SYSTSPRT (FINIS STEM FOO.)"                                    
  1980.                                                                                 
  1981. A downside is that if the REXX exec finds anomalous conditions                  
  1982. or executes a TSO command that barfs, standard TSO command output               
  1983. will probably get lost.  Therefore, try to use OUTTRAP to capture               
  1984. command output and test for error codes, and write all captured                 
  1985. output or error messages to SYSTSPRT in such a way as to allow                  
  1986. the client to see them (but not treat them as normal directory                  
  1987. data or whatever).                                                              
  1988.                                                                                 
  1989. A helpful hack is to use an EXECUTE exec to invoke other REXX                   
  1990. code or TSO commands that normally output via PUTLINE.  e.g.:                   
  1991.                                                                                 
  1992. /* REXX. Usage: EXECUTE exec args... */                                         
  1993.                                                                                 
  1994.  parse arg real_exec_command                                                    
  1995.  parse source sourceline                                                        
  1996.  if word(sourceline,7) = "TSO" then do                                          
  1997.   x = outtrap("LINE.")                                                          
  1998.   real_exec_command                                                             
  1999.   arc = rc                                                                      
  2000.   x = outtrap("OFF")                                                            
  2001.   "EXECIO * DISKW SYSTSPRT (FINIS STEM LINE.)"                                  
  2002.  end                                                                            
  2003.  else do                                                                        
  2004.   real_exec_command                                                             
  2005.   arc = rc                                                                      
  2006.  end                                                                            
  2007.                                                                                 
  2008.  return arc                                                                     
  2009.                                                                                 
  2010. I don't recommend this, though, because it's SLOW.                              
  2011.                                                                                 
  2012.                                                                                 
  2013. If the Gopher server is a TSO-in-batch job (i.e. EXEC PGM=IKJEFT01)             
  2014. then you can issue TSO commands from the exec.  To get the output,              
  2015. though, you need to use OUTTRAP around them.  If they issue TPUT's,             
  2016. you are SOL.  If they are PL/1 programs that write to SYSPRINT, or              
  2017. FORTRAN or assembler, etc., allocate the SYSPRINT or FT06F001 or                
  2018. whatever file to a temporary and copy the temporary to SYSTSPRT.  If            
  2019. it is a C/370 program that writes to stdout or stderr, you may be able          
  2020. to use redirection:                                                             
  2021.                                                                                 
  2022.    CALL 'THEIR.LOAD(CPROG)' 'args > DD:SYSTSPRT'                                
  2023.                                                                                 
  2024.  for stdout                                                                     
  2025.                                                                                 
  2026.    CALL 'THEIR.LOAD(CPROG)' 'args 2> DD:SYSTSPRT'                               
  2027.                                                                                 
  2028.  for stderr                                                                     
  2029.                                                                                 
  2030.  (for multiple output, use >> instead of >)                                     
  2031.                                                                                 
  2032.  If gopher server is run straight batch rather than as a TSO job, then          
  2033.  you cannot run REXX execs that require a TSO environment.                      
  2034.                                                                                 
  2035.  One more important word:  Make sure that your SYSTSPRT file has a              
  2036.  large enough LRECL to handle the REXX output.  If it is too short,             
  2037.  the REXX output will get folded.  For TYPE=DIRECTORY in particular,            
  2038.  this is disastrous.  Recommended JCL for executing the Gopher server           
  2039.  may be found elsewhere in the installation materials, or your MVS              
  2040.  system programmer has probably already installed a Gopher server in            
  2041.  'SYS1.PROCLIB' or the equivalent with the correct allocation.                  
  2042.                                                                                 
  2043. What it is expected to return                                                   
  2044.                                                                                 
  2045.  OK - now the good stuff.  This depends on the TYPE on the menu entry           
  2046.  that your exec is trying to fulfill.  Some gopher protocol basics:             
  2047.                                                                                 
  2048.  A Gopher menu is really a text representation of the actual protocol,          
  2049.  which goes like this:                                                          
  2050.                                                                                 
  2051.  filetype -tab- name -tab- path -tab- host -tab- port                           
  2052.                                                                                 
  2053.  where -tab- is the EBCDIC (on MVS) or ASCII (on other box) tab                 
  2054.  character, and filetype is a single character.  The filetypes                  
  2055.  supported by the MVS Gopher server are:                                        
  2056.                                                                                 
  2057.  0 - flat file                                                                  
  2058.  1 - directory                                                                  
  2059.  2 - CSO                                                                        
  2060.  3 - error                                                                      
  2061.  7 - index                                                                      
  2062.  8 - TELNET                                                                     
  2063.  T - TN3270                                                                     
  2064.  w - whois (experimental)                                                       
  2065.                                                                                 
  2066.  To generate the equivalent of a Gopher menu, you must output data              
  2067.  in the above format.  Now for the details...                                   
  2068.                                                                                 
  2069. TYPE=FILE                                                                       
  2070.                                                                                 
  2071. Just return the straight data.  Try to avoid null lines because C/370           
  2072. believes they don't exist and will throw them away.  We hate this, but          
  2073. IBM is so hard to convince of reality sometimes...  Change all null             
  2074. lines to lines containing one blank as you write them out (you need to          
  2075. do this anyway if you are queueing output on the stack for EXECIO) and          
  2076. you will have no problems.                                                      
  2077.                                                                                 
  2078. TYPE=DIRECTORY                                                                  
  2079.                                                                                 
  2080. You must return lines that fit the gopher protocol format as above.             
  2081.                                                                                 
  2082. For example, if you want to generate a Gopher menu on the fly that              
  2083. is equivalent to this:                                                          
  2084.                                                                                 
  2085. type=file                                                                       
  2086. name=This is my description                                                     
  2087. path=some.gopher.path                                                           
  2088. host=sun1.sanjuan.com                                                           
  2089. port=70                                                                         
  2090.                                                                                 
  2091. then you output a line that looks like this:                                    
  2092.                                                                                 
  2093.   0This is my description!some.gopher.path!sun1.sanjuan.com!70                  
  2094.                                                                                 
  2095. (each ! is really a tab (EBCDIC hex 05) character)                              
  2096.                                                                                 
  2097. where "0" is the type (file in this example, but would be "1" for               
  2098. type=directory, "7" for typeindex, etc.)                                        
  2099.                                                                                 
  2100. Here's the REXX code that might do this:                                        
  2101.                                                                                 
  2102. name = "This is my description"                                                 
  2103. path = "some.gopher.path"                                                       
  2104. host = "sun1.sanjuan.com"                                                       
  2105. tab  = '05'x                                                                    
  2106. port = 70                                                                       
  2107.                                                                                 
  2108. queue "0"||name||tab||path||tab||host||tab||port                                
  2109.                                                                                 
  2110. Assuming we write the queued lines to DD SYSTSPRT, as described.                
  2111.                                                                                 
  2112. Specifying the Right Host Name                                                  
  2113.                                                                                 
  2114. Most of the time you will probably want to generate a menu item                 
  2115. that points back to your MVS host, not some other host.  It may                 
  2116. even redrive your selfsame REXX exec with new arguments.  And if                
  2117. the exec was invoked in local (serverless) mode, you want the item              
  2118. to get driven in the same mode, probably.                                       
  2119.                                                                                 
  2120. The question is - what's the easiest way to identify what                       
  2121. the "same server" is?  One way is to hardcode the server name (e.g.             
  2122. "MVS.DRAPER.COM"), but this is not sufficiently general because:                
  2123.                                                                                 
  2124. (1) the server name or location may change                                      
  2125. (2) you can't distribute the exec to other Gopher users                         
  2126. (3) it won't work the same way in "local mode"                                  
  2127.                                                                                 
  2128. So, you need a way to know what the name of your selfsame host is.              
  2129. The MVS Gopher server can use HOST=+, but you can't, as that isn't              
  2130. part of the Gopher protocol.  So what do you do?                                
  2131.                                                                                 
  2132. Recommendation:  call a function hostname() to return the current               
  2133. host name.  So in the above code segment, you might have:                       
  2134.                                                                                 
  2135.  host = hostname()                                                              
  2136.                                                                                 
  2137. What is that hostname() function anyway?                                        
  2138. Well, you create it.                                                            
  2139. Take your Gopher exec library (please) and include an exec                      
  2140. called HOSTNAME, which you set up to return the name                            
  2141. of the host that you want to be the "same host".                                
  2142.                                                                                 
  2143. Note that a plus sign "+" will not work in this context.                        
  2144. The plus sign is a hack interpreted by the Gopher server                        
  2145. when it sees it on a menu.  It is *not* part of the Gopher                      
  2146. protocol and therefore cannot be sent over.                                     
  2147.                                                                                 
  2148. However, the minus sign "-" will work, as the Gopher client                     
  2149. in local mode will interpret it at the protocol level                           
  2150. (which DOES NOT IMPLY THAT IT IS A PART OF THE STANDARD                         
  2151. GOPHER PROTOCOL, PROPOSED OR OTHERWISE - THIS IS JUST A                         
  2152. LOCAL HACK MODIFICATION).                                                       
  2153.                                                                                 
  2154. Anyhow, what you ought to do is to have different Gopher                        
  2155. exec libraries for local (i.e.private) use and public                           
  2156. server use.  The public server will have a HOSTNAME member                      
  2157. that says                                                                       
  2158.                                                                                 
  2159.  return "MVS.DRAPER.COM"                                                        
  2160.                                                                                 
  2161. or whatever the name of *YOUR* gopher server host is.                           
  2162.                                                                                 
  2163. Your private exec library should have a HOSTNAME member                         
  2164. that says                                                                       
  2165.                                                                                 
  2166.   return "-"                                                                    
  2167.                                                                                 
  2168. This is the best I can come up with right now.  A future enhancement            
  2169. may be to pass the hostname as the second arg to the REXX exec using            
  2170. the IRXEXEC interface, e.g.                                                     
  2171.                                                                                 
  2172. parse arg execargs, hostname                                                    
  2173.                                                                                 
  2174. Then we could pass even more such arguments, like port, etc.                    
  2175. But that's all for now...                                                       
  2176.                                                                                 
  2177.                                                                                 
  2178. Oh, one more thing!  The same principle applies to the port number.             
  2179. Yes, it's normally 70 for Gopher.  But if you're running a server               
  2180. off a different port - like the example of running two MVS Gopher               
  2181. servers you saw if you read the installation files - then you will              
  2182. not want to hardcode a port number either.                                      
  2183.                                                                                 
  2184. So in all the above examples, change the statements that read                   
  2185. "port = 70" or the like so that they read                                       
  2186.                                                                                 
  2187. port = port()                                                                   
  2188.                                                                                 
  2189. and define a PORT exec in your library, sort of like the HOSTNAME exec,         
  2190. that reads                                                                      
  2191.                                                                                 
  2192. return "70"            /* if you want to talk to the primary server */          
  2193.                                                                                 
  2194.  or                                                                             
  2195.                                                                                 
  2196. return "1570"          /* use secondary Gopher server */                        
  2197.                                                                                 
  2198. Note that in our recommended scenario, we always use the secondary              
  2199. server for exec requests and the primary server for file requests.              
  2200. So, if you are building a menu item whose path is a file name, use              
  2201. the primary server port; if you are building a menu item whose path             
  2202. is a REXX exec specification, use the secondary server port.                    
  2203.                                                                                 
  2204. ./   ADD NAME=ABOUTS,SSI=01050001                                               
  2205. gopher_menu                                                                     
  2206.                                                                                 
  2207. TYPE=FILE                                                                       
  2208. NAME=Creating MVS Gopher Menus                                                  
  2209. PATH=(ABOUTCSM)                                                                 
  2210. HOST=+                                                                          
  2211. END                                                                             
  2212.                                                                                 
  2213. TYPE=FILE                                                                       
  2214. NAME=MVS Gopher Access Table                                                    
  2215. PATH=(ABOUTSA)                                                                  
  2216. HOST=+                                                                          
  2217. END                                                                             
  2218.                                                                                 
  2219. TYPE=FILE                                                                       
  2220. NAME=MVS Gopher Startup Parameters                                              
  2221. PATH=(ABOUTSP)                                                                  
  2222. HOST=+                                                                          
  2223. END                                                                             
  2224.                                                                                 
  2225. TYPE=FILE                                                                       
  2226. NAME=REXX Exec Interface                                                        
  2227. PATH=(ABOUTCSX)                                                                 
  2228. HOST=+                                                                          
  2229. END                                                                             
  2230.                                                                                 
  2231. ./   ADD NAME=ABOUTSA,SSI=01020004                                              
  2232.                                                                                 
  2233.   Format of entries in the Gopher Access Table:                                 
  2234.                                                                                 
  2235.   filename (fully qualified, all uppercase, no quotes)                          
  2236.   can be "DD:DDNAME" or "EXEC:EXECNAME"                                         
  2237.                                                                                 
  2238.   followed by names of hosts which are authorized to access the data.           
  2239.   If no host name list is present, all hosts are authorized                     
  2240.                                                                                 
  2241.   You may specify the same file name more than once, if you need                
  2242.   more lines to put host names on.                                              
  2243.                                                                                 
  2244.   Individual PDS members must be specified separately.  A PDS without           
  2245.   a member name establishes access only to the PDS directory.                   
  2246.                                                                                 
  2247.   Note that the default directory MUST be in this table.                        
  2248.                                                                                 
  2249.   Also note that in the case of EXECs, the EXEC must live in the                
  2250.   library allocated to GGEXEC in the Gopher server JCL.                         
  2251.                                                                                 
  2252.   *** ANY DATA SET REFERENCED BY ANY EXEC IN THAT LIBRARY IS FULLY              
  2253.   *** ACCESSIBLE TO GOPHER REGARDLESS OF THIS TABLE!  USE THIS TABLE            
  2254.   *** TO GOVERN CONTROL TO THE EXEC ITSELF!!!                                   
  2255.                                                                                 
  2256. ./   ADD NAME=ABOUTSP,SSI=01000044                                              
  2257.                                                                                 
  2258.  MVS Gopher Startup Parameter File                                              
  2259.                                                                                 
  2260.  The Gopher server started task may contain a DD statement pointing             
  2261.  to DDname GGPARMS.  If so, this file contains startup parameters               
  2262.  for that invocation of the server.  If such a file does not exist,             
  2263.  the defaults (as in the header file GGUSER) are used.                          
  2264.                                                                                 
  2265.  One possible use of this feature is to have more than one MVS Gopher           
  2266.  server running, with different port numbers.  This may prevent some            
  2267.  bottlenecking situations.                                                      
  2268.                                                                                 
  2269.  All entries in this file have the format:   variable value comments            
  2270.                                                                                 
  2271.  These are the possible values and their default settings:                      
  2272.                                                                                 
  2273.  mtftasks 1    Number of concurrent subtasks to handle client requests          
  2274.  port     70   The TCP port number by which clients connect                     
  2275.  qlength  20   Queue length for TCP server listen function                      
  2276.  timeout  60   Connection timeout specified when socket is closed               
  2277.  domain   .DRAPER.COM     The suffix to be appende to bald host names           
  2278.                                                                                 
  2279. You may notice that the TELNET command may be set in this file too.             
  2280. That was probably a misunderstanding, as it's the client, not the               
  2281. server, that controls how telnets are to be done.                               
  2282.                                                                                 
  2283. ./   ADD NAME=ABOUTW,SSI=01020053                                               
  2284. What is Gopher?                                                                 
  2285.                                                                                 
  2286. For more information, read the FAQ, posted to USENET newsgroups                 
  2287. comp.infosystems.gopher and news.answers every two weeks.                       
  2288.                                                                                 
  2289. The information contained here is borrowed therefrom in large part.             
  2290.                                                                                 
  2291. Gopher is a client/server protocol for building a distributed                   
  2292. information delivery service.  While providing a delivery vehicle for           
  2293. local information, Gopher also facilitates access to other Gopher and           
  2294. information servers on the Internet.                                            
  2295.                                                                                 
  2296. Gopher servers and clients can be obtained via anonymous ftp to                 
  2297. boombox.micro.umn.edu.  Look in the directory /pub/gopher.                      
  2298.                                                                                 
  2299.      There are clients for the following systems.  For the latest               
  2300.      directory information, see the FAQ.                                        
  2301.                                                                                 
  2302.       Unix Curses & Emacs                                                       
  2303.       Xwindows                                                                  
  2304.       Macintosh Hypercard                                                       
  2305.       Macintosh Application                                                     
  2306.       DOS w/Clarkson Driver                                                     
  2307.       NeXTstep                                                                  
  2308.       VM/CMS                                                                    
  2309.       VMS                                                                       
  2310.       MVS                                                                       
  2311.                                                                                 
  2312.      There are also a number of public telnet login sites available.            
  2313.      See the FAQ for more information.                                          
  2314.                                                                                 
  2315.      There are servers for the following systems.  For the latest               
  2316.      directory information, see the FAQ.                                        
  2317.                                                                                 
  2318.        Unix                                                                     
  2319.        VMS                                                                      
  2320.        Macintosh                                                                
  2321.        VM/CMS                                                                   
  2322.        MVS                                                                      
  2323.                                                                                 
  2324.                                                                                 
  2325. Papers and articles describing Gopher:                                          
  2326.                                                                                 
  2327.      _The_Internet_Gopher_, "ConneXions", July 1992, Interop.                   
  2328.                                                                                 
  2329.      _Exploring_Internet_GopherSpace_ "The Internet Society News", v1n2 1992,   
  2330.                                                                                 
  2331.      _The_Internet_Gopher_Protocol_, Proceedings of the Twenty-Third            
  2332.           IETF, CNRI, Section 5.3                                               
  2333.                                                                                 
  2334.      _Internet_Gopher_, Proceedings of Canadian Networking '92                  
  2335.                                                                                 
  2336.      _The_Internet_Gopher_, INTERNET: Getting Started, SRI                      
  2337.           International, Section 10.5.5                                         
  2338.                                                                                 
  2339.      _Tools_help_Internet_users_discover_on-line_treasures, Computerworld,      
  2340.           July 20, 1992                                                         
  2341.                                                                                 
  2342.      Gopher will also be in two forthcoming O'Reilly Books:                     
  2343.      "Administrating TCP/IP, and The Whole Internet"                            
  2344.                                                                                 
  2345. ./   ADD NAME=FAQ,SSI=01030010                                                  
  2346. Xref: news.draper.com comp.infosystems.gopher:3051 news.answers:5459 comp.answer
  2347. Newsgroups: comp.infosystems.gopher,news.answers,comp.answers                   
  2348. Path: news.draper.com!ns.draper.com!noc.near.net!howland.reston.ans.net!gatech!n
  2349. From: gopher@boombox.micro.umn.edu (UofMN Gopher Team)                          
  2350. Subject: Gopher (comp.infosystems.gopher) Frequently Asked Questions (FAQ)      
  2351. Message-ID: <goher-faq_03-26-93@mudhoney.micro.umn.edu>                         
  2352. Followup-To: comp.infosystems.gopher                                            
  2353. Summary: Common Questions and Answers about the Internet Gopher, a              
  2354.         client/server protocol for making a world wide information              
  2355.         service, with many implementations.                                     
  2356. Sender: news@news.cis.umn.edu (Usenet News Administration)                      
  2357. Supersedes: <gopher-faq_02-19-93@mudhoney.micro.umn.edu>                        
  2358. Nntp-Posting-Host: mudhoney.micro.umn.edu                                       
  2359. Reply-To: gopher@boombox.micro.umn.edu (UofMN Gopher Team)                      
  2360. Organization: University of Minnesota                                           
  2361. Date: Fri, 26 Mar 1993 09:29:40 GMT                                             
  2362. Approved: news-answers-request@MIT.Edu                                          
  2363. Lines: 562                                                                      
  2364.                                                                                 
  2365. Archive-name: gopher-faq                                                        
  2366. Last-modified: 1993/03/11                                                       
  2367.                                                                                 
  2368. Common Questions and Answers about the Internet Gopher, a                       
  2369. client/server protocol for making a world wide information service,             
  2370. with many implementations.  Posted to comp.infosystems.gopher,                  
  2371. comp.answers, and news.answers every two weeks.                                 
  2372.                                                                                 
  2373. The most recent version of this FAQ can be gotten through gopher, or            
  2374. via anonymous ftp:                                                              
  2375.                                                                                 
  2376. pit-manager.mit.edu:/pub/usenet/news.answers/gopher-faq                         
  2377.                                                                                 
  2378. Those without FTP access should send e-mail to mail-server@rtfm.mit.edu         
  2379. with "send usenet/news.answers/finding-sources" in the body to find out         
  2380. how to do FTP by e-mail.                                                        
  2381.                                                                                 
  2382. -------------------------------------------------------------------             
  2383. List of questions in the Gopher FAQ:                                            
  2384.                                                                                 
  2385. Q0:  What is Gopher?                                                            
  2386. Q1:  Where can I get Gopher software?                                           
  2387. Q2:  What do I need to access Gopher?                                           
  2388. Q3:  Where are there publicly available logins for Gopher?                      
  2389. Q4:  How can I add to the information in gopher?                                
  2390. Q5:  Who Develops Gopher Software?                                              
  2391. Q6:  How can I set up a "CSO" phone book server?  Where is the software?        
  2392. Q7:  Why can't I access the University of Minnesota's UPI news?                 
  2393. Q9:  What are the type characters for the different Gopher Objects?             
  2394. Q10: When I do full-text searches I always get every document back, Why?        
  2395. Q11: When I try to build the UNIX software I get an error from make:            
  2396.      "Must be a separator on rules line #. Stop"  Why?                          
  2397. Q12: What is the relationship between Gopher and (WAIS, WWW, ftp)?              
  2398. Q13: Are papers or articles describing Gopher available?                        
  2399. Q14: On a DECstation I get the error message "/etc/svc.conf no such file        
  2400.      or directory" when running the gopherd server, why?                        
  2401. Q15: The boolean searching terms don't work for my full-text index, why?        
  2402. Q16: When linking the Unix gopher server with WAIS I get undefined symbols,     
  2403. Q18: Why don't my WAIS indexes work?  I never get anything back for searches.   
  2404.      or Why do I get "Dangling file" error messages in my logfile?              
  2405. Q19: My gopher server doesn't work under inetd, why?                            
  2406. Q20: This is not a bug report, just a curiousity. I managed to install          
  2407. Q21: Help!  I have PC-NFS and want to use the PC-Gopher client.  How?           
  2408. Q22: How do I nuke a hung TCP connection?  I can't restart my UNIX              
  2409.      gopher server unless I get rid of it, and I don't want to reboot!          
  2410. Q23: Is there somewhere I can retrieve a list of announced gopher               
  2411.      links?  I'd like to keep a local, up-to-date list of available gopher      
  2412.      holes without requiring our users to gopher to umn just to scan            
  2413.      GopherSpace.                                                               
  2414. Q24: Why doesn't my unix gopher client display ISO-Latin-1 characters           
  2415. Q25: What is veronica?                                                          
  2416.                                                                                 
  2417. -------------------------------------------------------------------             
  2418. Q0:  What is Gopher?                                                            
  2419.                                                                                 
  2420. A0:  The Internet Gopher client/server provides a distributed                   
  2421.      information delivery system around which a world/campus-wide               
  2422.      information system (CWIS) can readily be constructed.   While              
  2423.      providing a delivery vehicle for local information,  Gopher                
  2424.      facilitates access to other Gopher and information servers                 
  2425.      throughout the world.                                                      
  2426.                                                                                 
  2427. -------------------------------------------------------------------             
  2428. Q1:  Where can I get Gopher software?                                           
  2429.                                                                                 
  2430. A1:  via anonymous ftp to boombox.micro.umn.edu.  Look in the directory         
  2431.      /pub/gopher                                                                
  2432.                                                                                 
  2433. --------------------------------------------------------------------            
  2434. Q2:  What do I need to access Gopher?                                           
  2435.                                                                                 
  2436. A2:  You will need a gopher "client" program that runs on your local PC         
  2437.      or workstation                                                             
  2438.                                                                                 
  2439.      There are clients for the following systems.  The directory                
  2440.      following the name is the location of the client on the anonymous          
  2441.      ftp site boombox.micro.umn.edu (134.84.132.2) in the directory             
  2442.      /pub/gopher.                                                               
  2443.                                                                                 
  2444.       Unix Curses & Emacs   :  /pub/gopher/Unix/gopher1.12.tar.Z                
  2445.       Xwindows (athena)     :  /pub/gopher/Unix/xgopher1.2.tar.Z                
  2446.       Xwindows (Motif)      :  /pub/gopher/Unix/moog                            
  2447.       Macintosh Hypercard   :  /pub/gopher/Macintosh-TurboGopher/old-versions * 
  2448.       Macintosh Application :  /pub/gopher/Macintosh-TurboGopher *              
  2449.       DOS w/Clarkson Driver :  /pub/gopher/PC_client/                           
  2450.       NeXTstep              :  /pub/gopher/NeXT/                                
  2451.       VM/CMS                :  /pub/gopher/Rice_CMS/ or /pub/gopher/VieGOPHER/  
  2452.       VMS                   :  /pub/gopher/VMS/                                 
  2453.       OS/2 2.0              :  /pub/gopher/os2/                                 
  2454.       MVS/XA                :  /pub/gopher/mvs/                                 
  2455.                                                                                 
  2456.      Many other clients and servers have been developed by others, the          
  2457.      following is an attempt at a comprehensive list.                           
  2458.                                                                                 
  2459.       A Microsoft Windows Winsock client "The Gopher Book"                      
  2460.         sunsite.unc.edu:/pub/micro/pc-stuff/ms-windows/winsock/goph_tbk.zip     
  2461.                                                                                 
  2462.       A Macintosh Application, "MacGopher".                                     
  2463.         ftp.cc.utah.edu:/pub/gopher/Macintosh *                                 
  2464.                                                                                 
  2465.       Another Macintosh application, "GopherApp".                               
  2466.         ftp.bio.indiana.edu:/util/gopher/gopherapp *                            
  2467.                                                                                 
  2468.       A port of the UNIX curses client for DOS with PC/TCP                      
  2469.         oac.hsc.uth.tmc.edu:/public/dos/misc/dosgopher.exe                      
  2470.                                                                                 
  2471.       A port of the UNIX curses client for PC-NFS                               
  2472.          bcm.tmc.edu:/nfs/gopher.exe                                            
  2473.                                                                                 
  2474.       A beta version of the PC Gopher client for Novell's LAN Workplace         
  2475.       for DOS                                                                   
  2476.          lennon.itn.med.umich.edu:/dos/gopher                                   
  2477.                                                                                 
  2478.       A VMS DECwindows client for use with Wollongong or UCX                    
  2479.          job.acs.ohio-state.edu:XGOPHER_CLIENT.SHARE                            
  2480.                                                                                 
  2481.                                                                                 
  2482.      * Note: these Macintosh clients require MacTCP.                            
  2483.                                                                                 
  2484.      Most of the above clients can also be fetched via a gopher client          
  2485.      itself.  Put the following on a gopher server:                             
  2486.                                                                                 
  2487.        Type=1                                                                   
  2488.        Host=boombox.micro.umn.edu                                               
  2489.        Port=70                                                                  
  2490.        Path=                                                                    
  2491.        Name=Gopher Software Distribution.                                       
  2492.                                                                                 
  2493.                                                                                 
  2494.      Or point your gopher client at boombox.micro.umn.edu, port 70 and          
  2495.      look in the gopher directory.                                              
  2496.                                                                                 
  2497.                                                                                 
  2498.      There are also a number of public telnet login sites available.            
  2499.      The University of Minnesota operates one on the machine                    
  2500.      "consultant.micro.umn.edu" (134.84.132.4) See Q3 for more                  
  2501.      information about this.  It is recommended that you run the client         
  2502.      software instead of logging into the public telnet login sites.  A         
  2503.      client uses the custom features of the local machine (mouse,               
  2504.      scroll bars, etc.)  A local client is also faster.                         
  2505.                                                                                 
  2506. ---------------------------------------------------------------------           
  2507. Q3:  Where are there publicly available logins for Gopher?                      
  2508.                                                                                 
  2509. A3:  Here is a short list, use the site closest to you to minimize              
  2510.      network lag.                                                               
  2511.                                                                                 
  2512.      Non-tn3270 Public Logins:                                                  
  2513.                                                                                 
  2514.      Hostname                  IP#              Login   Area                    
  2515.      ------------------------- ---------------  ------  -------------           
  2516.      consultant.micro.umn.edu  134.84.132.4     gopher  North America           
  2517.      gopher.uiuc.edu           128.174.33.160   gopher  North America           
  2518.      panda.uiowa.edu           128.255.40.201   panda   North America           
  2519.      gopher.sunet.se           192.36.125.2     gopher  Europe                  
  2520.      info.anu.edu.au           150.203.84.20    info    Australia               
  2521.      gopher.chalmers.se        129.16.221.40    gopher  Sweden                  
  2522.      tolten.puc.cl             146.155.1.16     gopher  South America           
  2523.      ecnet.ec                  157.100.45.2     gopher  Ecuador                 
  2524.                                                                                 
  2525.      tn3270 Public Logins:                                                      
  2526.                                                                                 
  2527.      Hostname                  IP#              Login   Area                    
  2528.      ------------------------- ---------------  ------  -------------           
  2529.      pubinfo.ais.umn.edu       128.101.109.1    -none-  North America           
  2530.                                                                                 
  2531.                                                                                 
  2532.      It is recommended that you run the client software instead of              
  2533.      logging into the public login sites.  A client uses the                    
  2534.      custom features of the local machine (mouse, scroll bars, etc.)            
  2535.      and gives faster response.                                                 
  2536.                                                                                 
  2537. ---------------------------------------------------------------------           
  2538. Q4:  How can I add to the information in gopher?                                
  2539.                                                                                 
  2540. A4:  You can do this by running a gopher server.  Servers are available         
  2541.      for a number of systems.  Use anonymous ftp to                             
  2542.      boombox.micro.umn.edu (134.84.132.2) and look in /pub/gopher.  The         
  2543.      following servers are available there:                                     
  2544.                                                                                 
  2545.        Unix      : /pub/gopher/Unix/gopherxx.tar.Z                              
  2546.        VMS       : /pub/gopher/VMS/                                             
  2547.        Macintosh : /pub/gopher/Mac_server/                                      
  2548.        VM/CMS    : /pub/gopher/Rice_CMS/ or /pub/gopher/Vienna_CMS/             
  2549.        MVS       : /pub/gopher/mvs/                                             
  2550.        DOS PC    : /pub/gopher/PC_server/                                       
  2551.                                                                                 
  2552.                                                                                 
  2553.      When you have your server ready you can publish it to the world by         
  2554.      sending e-mail to the maintainters of the "Other gophers" list:            
  2555.                                                                                 
  2556.      If your gopher server is in Europe, send mail to:                          
  2557.                                                                                 
  2558.         gopher@ebone.net                                                        
  2559.                                                                                 
  2560.      Otherwise send mail to:                                                    
  2561.                                                                                 
  2562.         gopher@boombox.micro.umn.edu                                            
  2563.                                                                                 
  2564. ---------------------------------------------------------------------           
  2565. Q5:  Who Develops Gopher Software?                                              
  2566.                                                                                 
  2567. A5:  Gopher was originally developed in April 1991 by the University            
  2568.      of Minnesota Microcomputer, Workstation, Networks Center to help           
  2569.      our campus find answers to their computer questions.                       
  2570.                                                                                 
  2571.      It has since grown into a full-fledged World Wide Information              
  2572.      System used by a large number of sites in the world.                       
  2573.                                                                                 
  2574.      Many people have contributed to the project, too numerous to               
  2575.      count.                                                                     
  2576.                                                                                 
  2577.      The people behind the much of the gopher software can be reached           
  2578.      via e-mail at gopher@boombox.micro.umn.edu, or via paper mail:             
  2579.                                                                                 
  2580.       Internet Gopher Developers                                                
  2581.       100 Union St. SE #190                                                     
  2582.       Minneapolis, MN 55455  USA                                                
  2583.                                                                                 
  2584.      Or via FAX at:                                                             
  2585.                                                                                 
  2586.       +1 (612) 625-6817                                                         
  2587.                                                                                 
  2588. ---------------------------------------------------------------------           
  2589. Q6:  How can I set up a "CSO" phone book server?  Where is the software?        
  2590.                                                                                 
  2591. A6:  CSO phone book servers are also known as "qi" servers.  The                
  2592.      software implementation can be gotten via anonymous ftp from               
  2593.      uxc.cso.uiuc.edu (128.174.5.50) as /pub/qi.tar.Z.  You may also            
  2594.      see this referred to as "ph", which is what most of the clients            
  2595.      are called.  A collected set of clients for Macs, PCs, VMS, VM,            
  2596.      etc, are in the /pub/ph.tar.Z file.                                        
  2597.                                                                                 
  2598.      There is also an archive of the mailing list for qi/ph software on         
  2599.      the same machine.  It's in /pub/info-ph.archive. You may join the          
  2600.      list by sending email to info-ph-request@uxc.cso.uiuc.edu.                 
  2601.                                                                                 
  2602.      This software is supported by Paul Pomes <p-pomes@uiuc.edu>                
  2603.      Contact him for more information.                                          
  2604.                                                                                 
  2605. -------------------------------------------------------------------             
  2606. Q7:  Why can't I access the University of Minnesota's UPI news?                 
  2607.                                                                                 
  2608. A7:  The University of Minnesota has a site license for UPI news, we            
  2609.      are not allowed to distribute it off of our campus.  We get our            
  2610.      UPI news from Clarinet.  For more information about getting UPI            
  2611.      news send mail to info@clarinet.com.  For information about                
  2612.      setting up your own gopher-UPI server search the gopher-news               
  2613.      archive for UPI.                                                           
  2614.                                                                                 
  2615. -------------------------------------------------------------------             
  2616. Q9:  What are the type characters for the different Gopher Objects?             
  2617.                                                                                 
  2618. A9:  Normal IDs.                                                                
  2619.                                                                                 
  2620.      0       Item is a file                                                     
  2621.      1       Item is a directory                                                
  2622.      2       Item is a CSO (qi) phone-book server                               
  2623.      3       Error                                                              
  2624.      4       Item is a BinHexed Macintosh file.                                 
  2625.      5       Item is DOS binary archive of some sort.                           
  2626.      6       Item is a UNIX uuencoded file.                                     
  2627.      7       Item is an Index-Search server.                                    
  2628.      8       Item points to a text-based telnet session.                        
  2629.      9       Item is a binary file!  Client must read until the connection      
  2630.                  closes.  Beware.                                               
  2631.      T       TN3270 connection.                                                 
  2632.                                                                                 
  2633.      Experimental IDs.                                                          
  2634.                                                                                 
  2635.      s       Sound type.  Data stream is a mulaw sound.                         
  2636.      g       GIF type.                                                          
  2637.      M       MIME type.  Item contains MIME data.                               
  2638.      h       html type.                                                         
  2639.      I       Image type.                                                        
  2640.      i       "inline" text type (used by panda).                                
  2641.                                                                                 
  2642. -------------------------------------------------------------------             
  2643. Q10: When I do full-text searches I always get every document back, Why?        
  2644.                                                                                 
  2645. A10: This is a problem occasionally encountered with Unix full-text             
  2646.      indexes.  It is caused by setting up the link incorrectly to a             
  2647.      gindexd port.                                                              
  2648.                                                                                 
  2649.      The Path= field should be *blank* when pointing to a gindexd               
  2650.      index.                                                                     
  2651.                                                                                 
  2652.      Otherwise the client will send the path to the gindexd daemon,             
  2653.      which interprets everything as a keyword.  This path is                    
  2654.      likely to contain a pathname that is common to all of the indexed          
  2655.      files.  Thus a search generates hits on everything.                        
  2656.                                                                                 
  2657. -------------------------------------------------------------------             
  2658. Q11: When I try to build the UNIX software I get an error from make:            
  2659.      "Must be a separator on rules line #. Stop"  Why?                          
  2660.                                                                                 
  2661. A11: This is a problem with older makes that don't understand the "include"     
  2662.      keyword.  One easy way to cope with this problem is compiling GNU          
  2663.      make, which does understand the include keyword.                           
  2664.                                                                                 
  2665.      If this is too difficult, remove the line:                                 
  2666.                                                                                 
  2667.       include Makefile.config                                                   
  2668.                                                                                 
  2669.      from all the Makefiles and paste in a copy of Makefile.config at           
  2670.      the top of each Makefile.                                                  
  2671.                                                                                 
  2672.      Or, instead of pasting you can make the client/server by going             
  2673.      into the appropriate directory and typing:                                 
  2674.                                                                                 
  2675.       make -f ../Makefile.config -f Makefile                                    
  2676.                                                                                 
  2677. -------------------------------------------------------------------             
  2678. Q12: What is the relationship between Gopher and (WAIS, WWW, ftp)?              
  2679.                                                                                 
  2680. A12: Gopher is intimately intertwined with these two other systems.             
  2681.      As shipped the Unix gopher server has the capability to:                   
  2682.                                                                                 
  2683.        - Search local WAIS indices.                                             
  2684.        - Query remote WAIS servers and funnel the results to gopher             
  2685.          clients.                                                               
  2686.        - Query remote ftp sites and funnel the results to gopher                
  2687.          clients.                                                               
  2688.        - Be queried by WWW (World Wide Web) clients (either using               
  2689.          built in gopher querying or using native http querying.                
  2690.                                                                                 
  2691. -------------------------------------------------------------------             
  2692. Q13: Are papers or articles describing Gopher available?                        
  2693.                                                                                 
  2694. A13: Gopher has a whole chapter devoted to it in :                              
  2695.                                                                                 
  2696.      _The_Whole_Internet_users_guide_and_catalog by Ed Krol                     
  2697.      (publisher O'Reilley & Associates, Inc; ISBN: 1-56592-025-2).              
  2698.      (Editors note: ...Great book, go out and buy a bunch!)                     
  2699.                                                                                 
  2700.      _The_Internet_Passport: NorthWestNet's Guide to Our World Online"          
  2701.      By Jonathan Kochmer and NorthWestNet. Published by NorthWestNet,           
  2702.      Bellevue, WA. 1993. 516 pp. ISBN 0-9635281-0-6.                            
  2703.      Contact info: passport@nwnet.net, or (206) 562-3000                        
  2704.                                                                                 
  2705.      _A_Students_Guide_to_UNIX by Harley Hahn. (publisher McGraw Hill,          
  2706.      Inc.; 1993 ISBN 0-07-025511-3)                                             
  2707.                                                                                 
  2708.                                                                                 
  2709.      Other references include:                                                  
  2710.                                                                                 
  2711.      _The_Internet_Gopher_, "ConneXions", July 1992, Interop.                   
  2712.                                                                                 
  2713.      _Exploring_Internet_GopherSpace_ "The Internet Society News", v1n2 1992,   
  2714.                                                                                 
  2715.      (You can subscribe to the Internet Society News by sending e-mail to       
  2716.       isoc@nri.reston.va.us)                                                    
  2717.                                                                                 
  2718.      _The_Internet_Gopher_Protocol_, Proceedings of the Twenty-Third            
  2719.           IETF, CNRI, Section 5.3                                               
  2720.                                                                                 
  2721.      _Internet_Gopher_, Proceedings of Canadian Networking '92                  
  2722.                                                                                 
  2723.      _The_Internet_Gopher_, INTERNET: Getting Started, SRI                      
  2724.           International, Section 10.5.5                                         
  2725.                                                                                 
  2726.      _Tools_help_Internet_users_discover_on-line_treasures, Computerworld,      
  2727.           July 20, 1992                                                         
  2728.                                                                                 
  2729.      _TCP/IP_Network_Administration_, O'Reilly.                                 
  2730.                                                                                 
  2731.       Balakrishan, B. (Oct 1992)                                                
  2732.         "SPIGopher: Making SPIRES databases accessible through the              
  2733.       Gopher protocol".  SPIRES Fall '92 Workshop, Chapel Hill, North           
  2734.       Carolina.                                                                 
  2735.                                                                                 
  2736.       Tomer, C.  Information Technology Standards for Libraries,                
  2737.       _Journal of the American Society for Information Science_,                
  2738.       43(8):566-570, Sept 1992.                                                 
  2739.                                                                                 
  2740.                                                                                 
  2741. -------------------------------------------------------------------             
  2742. Q14: On a DECstation I get the error message "/etc/svc.conf no such file        
  2743.      or directory" when running the gopherd server, why?                        
  2744.                                                                                 
  2745. A14: This is caused by the chroot() call in gopherd.  It can be easily          
  2746.      fixed by running gopherd with the -c option.                               
  2747.                                                                                 
  2748.      Alternatively you can copy /etc/svc.conf into a directory named            
  2749.      "etc" inside the gopher-data directory.                                    
  2750. -------------------------------------------------------------------             
  2751. Q15: The boolean searching terms don't work for my full-text index, why?        
  2752.                                                                                 
  2753. A15: This is probably because the searching is being provided by WAIS.          
  2754.      WAIS opts to return all documents that contain a search phrase             
  2755.      within certain limits.  WAIS searches do return the documents with         
  2756.      the highest "score" at the top, those documents will have the              
  2757.      closest relevance.                                                         
  2758.                                                                                 
  2759.      Alternatively you could get a booleanized version of wais from             
  2760.      ftp.bio.indiana.edu.                                                       
  2761. -------------------------------------------------------------------             
  2762. Q16: When linking the Unix gopher server with WAIS I get undefined              
  2763.      symbols,                                                                   
  2764.        such as:                                                                 
  2765.                                                                                 
  2766.          log_file_name                                                          
  2767.          logfile                                                                
  2768.          PrintStatus                                                            
  2769.          find_value                                                             
  2770.          Sources                                                                
  2771.          NumSources                                                             
  2772.                                                                                 
  2773. A17: This happens if you make gopherd before linking in the WAIS ir/ui          
  2774.      directories.  The fix is to "make clean" or remove                         
  2775.      gopherd/{waisgopher.o,Waisindex.o} and then remake gopherd.  Or            
  2776.      link the ir/ui directories first.                                          
  2777. -------------------------------------------------------------------             
  2778. Q18: Why don't my WAIS indexes work?  I never get anything back for searches.   
  2779.      or Why do I get "Dangling file" error messages in my logfile?              
  2780.                                                                                 
  2781. A18: The problem could be in the server.  The server should be run              
  2782.      using the -c option if you want WAIS to work.  Another solution is to      
  2783.      patch the WAIS code so that it doesn't check the files on the disk.        
  2784.      Search the gopher-news archive for "dangling".  This will turn up a        
  2785.      single document with the patch.                                            
  2786.                                                                                 
  2787. -------------------------------------------------------------------             
  2788. Q19: My gopher server doesn't work under inetd, why?                            
  2789.                                                                                 
  2790. A19: It could be that your inetd server only supports a limited amount          
  2791.      of arguments.  For instance, the maximum number of arguments to an         
  2792.      inetd server is 5.  You can get around this by combining arguments: i.e.   
  2793.                                                                                 
  2794.        gopherd -I -c                                                            
  2795.                                                                                 
  2796.      becomes:                                                                   
  2797.                                                                                 
  2798.        gopherd -Ic                                                              
  2799.                                                                                 
  2800.      You may also leave the port specifier off of the command line.             
  2801.      The gopher server automagically finds out the port it's running on.        
  2802.                                                                                 
  2803. -------------------------------------------------------------------             
  2804. Q20: This is not a bug report, just a curiousity. I managed to install          
  2805.      gopher on my PC, more or less by myself, which is a pretty good            
  2806.      accomplishment, for someone who hasn't installed hardly anything on a      
  2807.      PC. I then proceeded to load my PC/TCP kernel, ETHDRV, and try to          
  2808.      start up gopher. It said it couldn't initialize that stack(?). I have      
  2809.      to load this whenever I use PC/TCP. Incredibly, when I did not load        
  2810.      ETHDRV, Gopher came up immediately and telneted to our local server.       
  2811.      How does it know what kernel to load?                                      
  2812.                                                                                 
  2813. A20 Dr. Science says,                                                           
  2814.                                                                                 
  2815.      The Internet Gopher program is not actually computer program at            
  2816.      all, but a collection of magical incantations handed down from Dark        
  2817.      Age conjurors.  It works by sending magical "demons" through the air,      
  2818.      which scour the world for information, and then return to cast             
  2819.      illusions containing the answer.                                           
  2820.                                                                                 
  2821.      When you use the Gopher, your computer isn't actually doing                
  2822.      anything at all.  Instead, these demons have mesmirized you with an        
  2823.      evil magical spell, which was invoked by the pattern of                    
  2824.      finger-movements peculiar to the typing of the letters G-O-P-H-E-R on      
  2825.      your keyboard.  This spell transmits demonic information directly to       
  2826.      your brain.                                                                
  2827.                                                                                 
  2828.      Scientists aren't certain of the long-term effects of demonic              
  2829.      mesmirization, although former presidents have suffered only minor         
  2830.      medical side-effects from it.  Indeed, since Magic and Science are         
  2831.      usually opposed to each other, most Scientists are usually                 
  2832.      close-minded about such issues, and will usually respond with some         
  2833.      vacuous non-answer about "packet drivers", "stacks", and other such        
  2834.      jargon.                                                                    
  2835.                                                                                 
  2836.      Unlike conventional scientists, Dr. Science is very open-minded and        
  2837.      is willing to deal with such issues in a frank and honest manner.          
  2838.      This is why people come to him with questions, and why they've learned     
  2839.      to rely on and live by his answers.                                        
  2840.                                                                                 
  2841.      Dr. Science                                                                
  2842.          "I'm not a real doctor;  I have a Master's Degree....  in SCIENCE!"    
  2843.                                                                                 
  2844. :-) :-) :-) :-)                                                                 
  2845. There's always room for a little humor in a FAQ..                               
  2846. -------------------------------------------------------------------             
  2847. Q21: Help!  I have PC-NFS and want to use the PC-Gopher client.  How?           
  2848.                                                                                 
  2849. A21: Use a piece of software called PKTMUX, available at fine ftp               
  2850.      sites everywhere.  This will let you use any packet driver                 
  2851.      application.                                                               
  2852.                                                                                 
  2853.      Or, aquire a client that supports PC-NFS.  See Q2.                         
  2854. -------------------------------------------------------------------             
  2855. Q22: How do I nuke a hung TCP connection?  I can't restart my UNIX              
  2856.      gopher server unless I get rid of it, and I don't want to reboot!          
  2857.                                                                                 
  2858. A22:                                                                            
  2859.                                                                                 
  2860. Here is an example of using dbx to change a socket from CLOSING to              
  2861. CLOSED.                                                                         
  2862.                                                                                 
  2863.  # netstat -A|grep CLOSING                                                      
  2864.  c4bc5100 tcp        0     11  mymachine.gopher 129.89.8.4.70  CLOSING          
  2865.  # dbx -k /vmunix /dev/mem                                                      
  2866.  ...                                                                            
  2867.  (dbx) 0xc4bc5100+8/1X                  -- display contents of PCB+8            
  2868.  c4bc5108:   00000007                                                           
  2869.  (dbx) assign 0xc4bc5108=0              -- zero it                              
  2870.  0                                                                              
  2871.  (dbx) q                                                                        
  2872.                                                                                 
  2873. After a minute or two, the CLOSED socket should disappear.                      
  2874. -------------------------------------------------------------------             
  2875. Q23: Is there somewhere I can retrieve a list of announced gopher               
  2876.      links?  I'd like to keep a local, up-to-date list of available gopher      
  2877.      holes without requiring our users to gopher to umn just to scan            
  2878.      GopherSpace.                                                               
  2879.                                                                                 
  2880. A23: In the Unix client/server distribution is a perl script called             
  2881.      "gopherdist". Gopherdist can fetch the contents of any point in            
  2882.      GopherSpace.                                                               
  2883.                                                                                 
  2884.      To dump the contents of all the North American links from                  
  2885.      gopher.tc.umn.edu do the following:                                        
  2886.                                                                                 
  2887.      % gopherdist gopher.tc.umn.edu 70 "1/Other Gopher and Information          
  2888.        Servers/North America" > .Links                                          
  2889. -------------------------------------------------------------------             
  2890. Q24: Why doesn't my unix gopher client display ISO-Latin-1 characters           
  2891.      properly?  BTW I'm using a Sun workstation..                               
  2892.                                                                                 
  2893. A24: It is the client's problem, the server is perfectly 8-bit transparent.     
  2894.      The BSD curses library uses bit 8 in order to remember, whether a          
  2895.      character has been displayed reverse. So use just /usr/5bin/cc and         
  2896.      you get the System V curses version which is 8 bit clean.                  
  2897.                                                                                 
  2898.      Note that this may be a problem under other versions of UNIX too...        
  2899.                                                                                 
  2900. -------------------------------------------------------------------             
  2901. Q25: What is veronica?                                                          
  2902.                                                                                 
  2903. A25: veronica:  Very Easy Rodent-Oriented Net-wide Index to                     
  2904.      Computerized Archives.                                                     
  2905.                                                                                 
  2906.      veronica offers a keyword search of most gopher-server menu titles         
  2907.      in the entire gopher web.  As archie is to ftp archives, veronica          
  2908.      is to gopherspace.  A veronica search produces a menu of gopher            
  2909.      items, each of which is a direct pointer to a gopher data source.          
  2910.      Because veronica is accessed through a gopher client, it is easy           
  2911.      to use, and gives access to all types of data supported by the             
  2912.      gopher protocol.                                                           
  2913.                                                                                 
  2914.      To try veronica, select it from the "Other Gophers" menu on                
  2915.      Minnesota's gopher server, or point your gopher at:                        
  2916.                                                                                 
  2917.      Name=veronica (search menu items in most of GopherSpace)                   
  2918.      Type=1                                                                     
  2919.      Port=70                                                                    
  2920.      Path=1/veronica                                                            
  2921.      Host=futique.scs.unr.edu                                                   
  2922. --                                                                              
  2923.  | Paul Lindner | lindner@boombox.micro.umn.edu   | Slipping into madness       
  2924.  |              | Computer & Information Services | is good for the sake        
  2925.  | Gophermaster | University of Minnesota         | of comparison.              
  2926. ///// / / /    /////// / / / /  /  /  /   /      //// / / / /  /  /  /   /      
  2927. ./ ENDUP                                                                        
  2928. ?!                                                                              
  2929. //C        EXEC GGLOAD,TRK1='18',TO='C'                                         
  2930. //SYSIN    DD DATA,DLM='?!'                                                     
  2931. ./   ADD NAME=GGCLIENT,SSI=01070025                                             
  2932.                                                                                 
  2933.  /********************************************************************/         
  2934.  /*                                                                  */         
  2935.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  2936.  /*                                                                  */         
  2937.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  2938.  /*                                                                  */         
  2939.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  2940.  /* including the implied warranties of merchantability and fitness, */         
  2941.  /* are expressly denied.                                            */         
  2942.  /*                                                                  */         
  2943.  /* Provided this copyright notice is included, this software may    */         
  2944.  /* be freely distributed and not offered for sale.                  */         
  2945.  /*                                                                  */         
  2946.  /* Changes or modifications may be made and used only by the maker  */         
  2947.  /* of same, and not further distributed.  Such modifications should */         
  2948.  /* be mailed to the author for consideration for addition to the    */         
  2949.  /* software and incorporation in subsequent releases.               */         
  2950.  /*                                                                  */         
  2951.  /********************************************************************/         
  2952.                                                                                 
  2953. #ifdef SASC                                                                     
  2954. #pragma  runopts(EXECOPS)                                                       
  2955. #else                                                                           
  2956. #pragma  runopts(heap(8k,8k,anywhere,))                                         
  2957. #pragma  runopts(nospie,nostae)                                                 
  2958. #endif                                                                          
  2959.                                                                                 
  2960. #pragma  csect(code,  "GG@LIENT")                                               
  2961. #pragma  csect(static,"GG$LIENT")                                               
  2962. #include "gg.h"                                                                 
  2963.                                                                                 
  2964. /*********************************************************************/         
  2965.                                                                                 
  2966. static char copyright_notice[] =                                                
  2967.    "Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992   \n\         
  2968.                                                                     \n\         
  2969.     GOPHER server due to Shawn Hart at the University of Delaware.  \n\         
  2970.                                                                     \n\         
  2971.     This software is provided on an 'AS IS' basis.  All warranties, \n\         
  2972.     including the implied warranties of merchantability and fitness,\n\         
  2973.     are expressly denied.                                           \n\         
  2974.                                                                     \n\         
  2975.     Provided this copyright notice is included, this software may   \n\         
  2976.     be freely distributed and not offered for sale.                 \n\         
  2977.                                                                     \n\         
  2978.     Changes or modifications may be made and used only by the maker \n\         
  2979.     of same, and not further distributed.  Such modifications should\n\         
  2980.     be mailed to the author for consideration for addition to the   \n\         
  2981.     software and incorporation in subsequent releases.";                        
  2982.                                                                                 
  2983. /*********************************************************************/         
  2984.                                                                                 
  2985. #ifdef I370                                                                     
  2986. char * _style = "tso:";                                                         
  2987. #endif                                                                          
  2988.                                                                                 
  2989. /*********************************************************************/         
  2990.                                                                                 
  2991. static void                                                                     
  2992. trap_ispf_command(gp,verb,action)                                               
  2993. Rstruc ggcb      *gp;                                                           
  2994. char             *verb;                                                         
  2995. char             *action;                                                       
  2996. {                                                                               
  2997.  char             zcttrunc [16];                                                
  2998.  char             zctact   [64];                                                
  2999.  char             zctdesc [128];                                                
  3000.                                                                                 
  3001.  if (!GGMivput(gp,"ZCTVERB ",verb,-1)) return;                                  
  3002.                                                                                 
  3003.  if (!GGMispf(gp,"TBTOP ISPCMDS")) return;                                      
  3004.  if (!GGMispf(gp,"TBSCAN ISPCMDS ARGLIST(ZCTVERB)")) return;                    
  3005.  if (!GGMivget(gp,"ZCTACT ",zctact,sizeof(zctact)))  return;                    
  3006.  if (UNEQUAL(zctact,action)) {                                                  
  3007.    GGMivget(gp,"ZCTTRUNC ",zcttrunc, sizeof(zcttrunc));                         
  3008.    GGMivget(gp,"ZCTDESC  ",zctdesc,sizeof(zctdesc));                            
  3009.    if (!GGMispf(gp,"TBTOP ISPCMDS ")) return;                                   
  3010.    GGMivput(gp,"ZCTACT   ",action   ,-1);                                       
  3011.    GGMivput(gp,"ZCTTRUNC ",zcttrunc ,-1);                                       
  3012.    GGMivput(gp,"ZCTDESC  ",zctdesc  ,-1);                                       
  3013.    if (!GGMispf(gp,"TBADD ISPCMDS ")) return;                                   
  3014.  }                                                                              
  3015.                                                                                 
  3016.  return;                                                                        
  3017. }                                                                               
  3018.                                                                                 
  3019. /*********************************************************************/         
  3020.                                                                                 
  3021. static Bool                                                                     
  3022. go_for_it(gp,ip)                                                                
  3023. struct ggcb            *gp;                                                     
  3024. struct gopherinfo      *ip;                                                     
  3025. {                                                                               
  3026.  char                   temp   [32];                                            
  3027.                                                                                 
  3028.  (void)GGMivget(gp,"GGHOST ",ip->host,sizeof(ip->host));                        
  3029.  (void)GGMivget(gp,"GGPATH ",ip->path,sizeof(ip->path));                        
  3030.  (void)GGMivget(gp,"GGDESC ",ip->desc,sizeof(ip->desc));                        
  3031.  (void)GGMivget(gp,"GGPORT ",temp    ,sizeof(temp)    );                        
  3032.  ip->type = INITIAL_TYPE;                                                       
  3033.  if (!*ip->path) strcpy(ip->path,INITIAL_PATH);                                 
  3034.  if (!*ip->host) strcpy(ip->host,INITIAL_HOST);                                 
  3035.  if (!*ip->desc) strcpy(ip->desc,INITIAL_DESC);                                 
  3036.  ip->port = atoi(temp);                                                         
  3037.  if (ip->port == 0) ip->port = INITIAL_PORT;                                    
  3038.  *ip->bmds = '\0';                                                              
  3039.                                                                                 
  3040.  return GGMgofor(gp,ip,FALSE);                                                  
  3041.                                                                                 
  3042. }                                                                               
  3043.                                                                                 
  3044. /*********************************************************************/         
  3045.                                                                                 
  3046. int                                                                             
  3047. main(argc,argv)                                                                 
  3048. int      argc;                                                                  
  3049. char   **argv;                                                                  
  3050.                                                                                 
  3051. {                                                                               
  3052.  struct ggcb            *gp;                                                    
  3053.  struct gopherinfo      *ip;                                                    
  3054.  struct connection      *sp;                                                    
  3055.  char                   *p;                                                     
  3056.  int                     i;                                                     
  3057.  int                     exit_return_code;                                      
  3058.  Bool                    bypass_startup;                                        
  3059.  struct ggcb             gg;                                                    
  3060.  char                    zerrsm [25];                                           
  3061.  char                    zerrlm [ZERRLM_SIZE];                                  
  3062.                                                                                 
  3063.  exit_return_code = 0;                                                          
  3064.                                                                                 
  3065.  memset(&gg,0,sizeof(struct ggcb));                                             
  3066.                                                                                 
  3067.  gp = ≫                                                                      
  3068.                                                                                 
  3069.  /* set up top-level gopherinfo structure */                                    
  3070.                                                                                 
  3071.  GETMAIN(ip, struct gopherinfo, 1, "top-level gopherinfo struct");              
  3072.  if (!ip) {                                                                     
  3073.    fprintf(stderr,"Not enough memory to start up GOPHER\n");                    
  3074.    exit(16);                                                                    
  3075.  }                                                                              
  3076.                                                                                 
  3077.  memset(ip,0,sizeof(struct gopherinfo));                                        
  3078.                                                                                 
  3079.  gp->ginfo = ip;                                                                
  3080.                                                                                 
  3081.  gp->test_mode  = FALSE;                                                        
  3082.  gp->debug_mode = FALSE;                                                        
  3083.  gp->local_mode = FALSE;                                                        
  3084.  bypass_startup = FALSE;                                                        
  3085.                                                                                 
  3086.  for (i = 1; i < argc; i++) {                                                   
  3087.    p = argv[i];                                                                 
  3088.    if (*p == '-') {                                                             
  3089.      while (*++p) {                                                             
  3090.        switch (toupper(*p)) {                                                   
  3091.          case 'T':  gp->test_mode  = TRUE;    break;                            
  3092.          case 'D':  gp->debug_mode = TRUE;    break;                            
  3093.          case 'L':  gp->local_mode = TRUE;    break;                            
  3094.          case 'Q':  bypass_startup = TRUE;    break;                            
  3095.          default: fprintf(stderr,"GGMVS: Bad parameter flag %c\n", *p);         
  3096.                   exit_return_code = 8;                                         
  3097.        }                                                                        
  3098.      }                                                                          
  3099.    }                                                                            
  3100.    else {                                                                       
  3101.      fprintf(stderr,"GGMVS: Bad parameter string %s\n",p);                      
  3102.      exit_return_code = 8;                                                      
  3103.    }                                                                            
  3104.  }                                                                              
  3105.                                                                                 
  3106.  if (gp->test_mode) __ctest(NULL);                                              
  3107.                                                                                 
  3108.  if (gp->debug_mode) {                                                          
  3109.    if (!(gp->debug_file = fopen(DEBUG_FILE,"w"))) {                             
  3110.      perror(DEBUG_FILE);                                                        
  3111.      exit_return_code = 4;                                                      
  3112.    }                                                                            
  3113.  }                                                                              
  3114.  else gp->debug_file = NULL;                                                    
  3115.                                                                                 
  3116.  gp->thdr.first_text_line = NULL;                                               
  3117.                                                                                 
  3118.  GGMclrtx(gp,NULL);               /* Clear text       */                        
  3119.  GGMclrtx(gp,ip);                 /* Clear text       */                        
  3120.                                                                                 
  3121.  sp = &gp->gopher_connection;                                                   
  3122.                                                                                 
  3123.  /* In the future these will be able to be set from gopherrc. */                
  3124.                                                                                 
  3125.  gp->myport   = SERV_TCP_PORT;                                                  
  3126.  gp->mytelnet = TELNET_COMMAND_NAME;                                            
  3127.  gp->mydomain = MY_DOMAIN_SUFFIX;                                               
  3128.                                                                                 
  3129.  /* Determine the local path name. Done in GGMCONN when needed now */           
  3130.                                                                                 
  3131.  strcpy(gp->ggserver,"");                                                       
  3132.  sp->connected_to_server   = FALSE;                                             
  3133.                                                                                 
  3134.  GETMAIN(sp->server_buf,    char,SERVER_BUF_MSGSIZE+4,"server buffer");         
  3135.  GETMAIN(sp->client_buf,    char,CLIENT_BUF_MSGSIZE+4,"client buffer");         
  3136.  GETMAIN(gp->gopher_command,char,CLIENT_BUF_MSGSIZE+4,"gopher command");        
  3137.                                                                                 
  3138. #ifdef FETCH                                                                    
  3139.                                                                                 
  3140.  gp->isplink_pointer = (int (*) ())fetch("ISPLINK");                            
  3141.  gp->ispexec_pointer = (int (*) ())fetch("ISPEXEC");                            
  3142.                                                                                 
  3143. #endif                                                                          
  3144.                                                                                 
  3145.  if (!GGMispf(gp,"CONTROL ERRORS RETURN")) exit_return_code = 20;               
  3146.                                                                                 
  3147.  else {                                                                         
  3148.                                                                                 
  3149.    exit_return_code = 0;                                                        
  3150.                                                                                 
  3151.    trap_ispf_command(gp,"RFIND","&YRFIND");  /* enable RFIND */                 
  3152.                                                                                 
  3153.    GGMsopt(gp,OPTION_ALL);      /* set options */                               
  3154.                                                                                 
  3155.    if (bypass_startup) {                                                        
  3156.      (void)GGMispf(gp,"VGET (GGHOST GGPATH GGDESC GGPORT) PROFILE");            
  3157.      (void)go_for_it(gp,ip);                                                    
  3158.    }                                                                            
  3159.    else {                                                                       
  3160.      (void)GGMivput(gp,"ZCMD "    ,"",-1);                                      
  3161.      while (GGMdispl(gp,"GGM     ") == 0                                        
  3162.          && !gp->quit                                                           
  3163.          && !go_for_it(gp,ip)) ;                                                
  3164.    }                                                                            
  3165.  }                                                                              
  3166.                                                                                 
  3167.  if (gp->setmsg) {                                                              
  3168.    (void)GGMivget(gp,"ZERRSM ",zerrsm, sizeof(zerrsm));                         
  3169.    (void)GGMivget(gp,"ZERRLM ",zerrlm, sizeof(zerrlm));                         
  3170.    fprintf(stderr,"%s: %s\n",zerrsm,zerrlm);                                    
  3171.    gp->setmsg = FALSE;                                                          
  3172.  }                                                                              
  3173.                                                                                 
  3174.  if (sp->connected_to_server) {                                                 
  3175.    GGMdisc(gp,sp);            /* disconnect from gopher server */               
  3176.  }                                                                              
  3177.                                                                                 
  3178.  FREEMAIN(gp->gopher_command,"gopher command");                                 
  3179.  FREEMAIN(sp->server_buf,    "server buffer");                                  
  3180.  FREEMAIN(sp->client_buf,    "client buffer");                                  
  3181.  FREEMAIN(gp->ginfo,         "top-level gopherinfo struct");                    
  3182.                                                                                 
  3183.  #define FINAL_CLOSE(A,B) \                                                     
  3184.    if (A) { \                                                                   
  3185.             if (fclose(A) < 0) fprintf(stderr,B); \                             
  3186.           }                                                                     
  3187.                                                                                 
  3188.  FINAL_CLOSE(gp->debug_file, "Error closing debug file\n");                     
  3189.                                                                                 
  3190.  exit(exit_return_code);                                                        
  3191. }                                                                               
  3192.                                                                                 
  3193. ./   ADD NAME=GGMALLOC                                                          
  3194.                                                                                 
  3195.  /********************************************************************/         
  3196.  /*                                                                  */         
  3197.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3198.  /*                                                                  */         
  3199.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3200.  /*                                                                  */         
  3201.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3202.  /* including the implied warranties of merchantability and fitness, */         
  3203.  /* are expressly denied.                                            */         
  3204.  /*                                                                  */         
  3205.  /* Provided this copyright notice is included, this software may    */         
  3206.  /* be freely distributed and not offered for sale.                  */         
  3207.  /*                                                                  */         
  3208.  /* Changes or modifications may be made and used only by the maker  */         
  3209.  /* of same, and not further distributed.  Such modifications should */         
  3210.  /* be mailed to the author for consideration for addition to the    */         
  3211.  /* software and incorporation in subsequent releases.               */         
  3212.  /*                                                                  */         
  3213.  /********************************************************************/         
  3214.                                                                                 
  3215. #pragma  csect(code,  "GG@ALLOC")                                               
  3216. #pragma  csect(static,"GG$ALLOC")                                               
  3217. #include "gg.h"                                                                 
  3218.                                                                                 
  3219. /****** Allocate a data set. *****************************************/         
  3220.                                                                                 
  3221. enum data_set_type                                                              
  3222. GGMalloc(dsname,ddname,wanted_type,nitems)                                      
  3223. char                      *dsname;                                              
  3224. char                      *ddname;                                              
  3225. enum data_set_type         wanted_type;                                         
  3226. int                        nitems;                                              
  3227. {                                                                               
  3228.  int                       i;                                                   
  3229.  int                       rc;                                                  
  3230.  char                     *cp;                                                  
  3231.  enum data_set_type        return_type;                                         
  3232.  Bool                      try_new;                                             
  3233.  short                     primary_allocation   ;                               
  3234.  short                     secondary_allocation ;                               
  3235.  short                     directory_blocks     ;                               
  3236.  short                     dsorg                ;                               
  3237.  __S99parms                stuff99; /* No "struct", despite manual */           
  3238.  TEXTUNIT                 *tu [17];                                             
  3239.  TEXTUNIT                  tu_dsn;                                              
  3240.  TEXTUNIT                  tu_ddn;                                              
  3241.  TEXTUNIT                  tu_member;                                           
  3242.  TEXTUNIT                  tu_stat;                                             
  3243.  TEXTUNIT                  tu_disp;                                             
  3244.  TEXTUNIT                  tu_perm;                                             
  3245.  TEXTUNIT                  tu_rtddn;                                            
  3246.  TEXTUNIT                  tu_rtorg;                                            
  3247.  TEXTUNIT                  tu_block;                                            
  3248.  TEXTUNIT                  tu_prime;                                            
  3249.  TEXTUNIT                  tu_sec;                                              
  3250.  TEXTUNIT                  tu_dir;                                              
  3251.  TEXTUNIT                  tu_recfm;                                            
  3252.  TEXTUNIT                  tu_lrecl;                                            
  3253.  TEXTUNIT                  tu_blksz;                                            
  3254.  TEXTUNIT                  tu_dsorg;                                            
  3255.  char                     *lparp;                                               
  3256.  char                     *rparp;                                               
  3257.  char                      dsnseq [81];                                         
  3258.  char                      member [81];                                         
  3259.  char                      what_to_open[81];                                    
  3260.  FILE                     *mfile;                                               
  3261.                                                                                 
  3262.  try_new = FALSE;                                                               
  3263.                                                                                 
  3264.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  3265.                                                                                 
  3266.  strcpy(member,"");                                                             
  3267.  strcpy(dsnseq,dsname);                                                         
  3268.  lparp = strchr(dsnseq,'(');                                                    
  3269.  rparp = strchr(dsnseq,')');                                                    
  3270.  if (lparp && rparp && (lparp < rparp) && (*(rparp+1) == '\0')) {               
  3271.    *lparp = '\0';            /* makes dsnseq the seq part only */               
  3272.    *rparp = '\0';            /* turns member into a string     */               
  3273.    strcpy(member, lparp+1);                                                     
  3274.    wanted_type = PDS;                                                           
  3275.  }                                                                              
  3276.                                                                                 
  3277.  for (;;) {                                                                     
  3278.                                                                                 
  3279.    stuff99.__S99RBLN   = 20;                                                    
  3280.    stuff99.__S99VERB   = S99VRBAL;                                              
  3281.    stuff99.__S99FLAG1  = S99NOCNV << 8;                                         
  3282.    stuff99.__S99ERROR  = 0;                                                     
  3283.    stuff99.__S99INFO   = 0;                                                     
  3284.    stuff99.__S99TXTPP  = tu;                                                    
  3285.    stuff99.__S99FLAG2  = 0;                                                     
  3286.                                                                                 
  3287.    i = 0;                                                                       
  3288.                                                                                 
  3289.    tu[i++] = &tu_dsn;                                                           
  3290.                                                                                 
  3291.    tu_dsn.key        = DALDSNAM;                                                
  3292.    tu_dsn.num        = 1;                                                       
  3293.    tu_dsn.ent.len    = strlen(dsnseq);                                          
  3294.    strcpy(tu_dsn.ent.prm,dsnseq);                                               
  3295.    for (cp=tu_dsn.ent.prm; *cp; cp++) *cp = toupper(*cp);                       
  3296.                                                                                 
  3297.    tu[i++] = &tu_stat;                                                          
  3298.                                                                                 
  3299.    tu_stat.key      = DALSTATS;                                                 
  3300.    tu_stat.num      = 1;                                                        
  3301.    tu_stat.ent.len  = 1;                                                        
  3302.    *tu_stat.ent.prm = (try_new ? NEW : SHR);                                    
  3303.                                                                                 
  3304.    tu[i++] = &tu_disp;                                                          
  3305.                                                                                 
  3306.    tu_disp.key      = DALNDISP;                                                 
  3307.    tu_disp.num      = 1;                                                        
  3308.    tu_disp.ent.len  = 1;                                                        
  3309.    *tu_disp.ent.prm = (try_new ? CATLG : KEEP);                                 
  3310.                                                                                 
  3311.    tu[i++] = &tu_rtorg;                                                         
  3312.                                                                                 
  3313.    tu_rtorg.key     = DALRTORG;                                                 
  3314.    tu_rtorg.num     = 1;                                                        
  3315.    tu_rtorg.ent.len = 2;                                                        
  3316.                                                                                 
  3317.    if (*member) {                                                               
  3318.                                                                                 
  3319.      tu[i++] = &tu_member;                                                      
  3320.                                                                                 
  3321.      tu_member.key     = DALMEMBR;                                              
  3322.      tu_member.num     = 1;                                                     
  3323.      tu_member.ent.len = strlen(member);                                        
  3324.      strcpy(tu_member.ent.prm,member);                                          
  3325.      for (cp=tu_member.ent.prm; *cp; cp++) *cp = toupper(*cp);                  
  3326.                                                                                 
  3327.    }                                                                            
  3328.                                                                                 
  3329.    if (ddname && *ddname) {                                                     
  3330.                                                                                 
  3331.      tu[i++] = &tu_ddn;                                                         
  3332.                                                                                 
  3333.      tu_ddn.key     = DALDDNAM;                                                 
  3334.      tu_ddn.num     = 1;                                                        
  3335.      tu_ddn.ent.len = strlen(ddname);                                           
  3336.      strcpy(tu_ddn.ent.prm,ddname);                                             
  3337.      for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);                     
  3338.                                                                                 
  3339.      tu[i++] = &tu_perm;                                                        
  3340.                                                                                 
  3341.      tu_perm.key     = DALPERMA;                                                
  3342.      tu_perm.num     = 0;                                                       
  3343.    }                                                                            
  3344.    else {                                                                       
  3345.                                                                                 
  3346.      tu[i++] = &tu_rtddn;                                                       
  3347.                                                                                 
  3348.      tu_rtddn.key     = DALRTDDN;                                               
  3349.      tu_rtddn.num     = 1;                                                      
  3350.      tu_rtddn.ent.len = 8;                                                      
  3351.      memset(tu_rtddn.ent.prm,' ',8);                                            
  3352.                                                                                 
  3353.    }                                                                            
  3354.                                                                                 
  3355.    if (try_new) {                                                               
  3356.                                                                                 
  3357.      switch (wanted_type) {                                                     
  3358.        case PDS:                                                                
  3359.                  primary_allocation   = (short)nitems;                          
  3360.                  secondary_allocation = primary_allocation;                     
  3361.                  directory_blocks     = ((short)nitems/(12*36)+1) * 36;         
  3362.                  dsorg                = DSORG_PO;                               
  3363.                  break;                                                         
  3364.        case SEQ:                                                                
  3365.        default:                                                                 
  3366.                  primary_allocation   = (short)nitems;                          
  3367.                  secondary_allocation = primary_allocation;                     
  3368.                  directory_blocks     = 0;                                      
  3369.                  dsorg                = DSORG_PS;                               
  3370.                  break;                                                         
  3371.      }                                                                          
  3372.                                                                                 
  3373.      tu[i++] = &tu_block;                                                       
  3374.                                                                                 
  3375.      tu_block.key     = DALBLKLN;                                               
  3376.      tu_block.num     = 1;                                                      
  3377.      tu_block.ent.len = 3;                                                      
  3378.      memset(tu_block.ent.prm,0,3);                                              
  3379.      *(short *)(tu_block.ent.prm+1) = 6233;                                     
  3380.                                                                                 
  3381.      tu[i++] = &tu_prime;                                                       
  3382.                                                                                 
  3383.      tu_prime.key     = DALPRIME;                                               
  3384.      tu_prime.num     = 1;                                                      
  3385.      tu_prime.ent.len = 3;                                                      
  3386.      memset(tu_prime.ent.prm,0,3);                                              
  3387.      *(short *)(tu_prime.ent.prm+1) = primary_allocation;                       
  3388.                                                                                 
  3389.      tu[i++] = &tu_sec;                                                         
  3390.                                                                                 
  3391.      tu_sec.key     = DALSECND;                                                 
  3392.      tu_sec.num     = 1;                                                        
  3393.      tu_sec.ent.len = 3;                                                        
  3394.      memset(tu_sec.ent.prm,0,3);                                                
  3395.      *(short *)(tu_sec.ent.prm+1) = secondary_allocation;                       
  3396.                                                                                 
  3397.      tu[i++] = &tu_dir;                                                         
  3398.                                                                                 
  3399.      tu_dir.key     = DALDIR;                                                   
  3400.      tu_dir.num     = 1;                                                        
  3401.      tu_dir.ent.len = 3;                                                        
  3402.      memset(tu_dir.ent.prm,0,3);                                                
  3403.      *(short *)(tu_dir.ent.prm+1) = directory_blocks;                           
  3404.                                                                                 
  3405.      tu[i++] = &tu_recfm;                                                       
  3406.                                                                                 
  3407.      tu_recfm.key        = DALRECFM;                                            
  3408.      tu_recfm.num        = 1;                                                   
  3409.      tu_recfm.ent.len    = 1;                                                   
  3410.      *tu_recfm.ent.prm   = RECFM_VB;                                            
  3411.                                                                                 
  3412.      tu[i++] = &tu_lrecl;                                                       
  3413.                                                                                 
  3414.      tu_lrecl.key        = DALLRECL;                                            
  3415.      tu_lrecl.num        = 1;                                                   
  3416.      tu_lrecl.ent.len    = 2;                                                   
  3417.      *(short *)tu_lrecl.ent.prm   = 259;                                        
  3418.                                                                                 
  3419.      tu[i++] = &tu_blksz;                                                       
  3420.                                                                                 
  3421.      tu_blksz.key        = DALBLKSZ;                                            
  3422.      tu_blksz.num        = 1;                                                   
  3423.      tu_blksz.ent.len    = 2;                                                   
  3424.      *(short *)tu_blksz.ent.prm   = 6233;                                       
  3425.                                                                                 
  3426.      tu[i++] = &tu_dsorg;                                                       
  3427.                                                                                 
  3428.      tu_dsorg.key        = DALDSORG;                                            
  3429.      tu_dsorg.num        = 1;                                                   
  3430.      tu_dsorg.ent.len    = 2;                                                   
  3431.      *(short *)tu_dsorg.ent.prm   = dsorg;                                      
  3432.                                                                                 
  3433.    }                                                                            
  3434.                                                                                 
  3435.    tu[i] = (void *)0x80000000;                                                  
  3436.                                                                                 
  3437.    rc = svc99(&stuff99);                                                        
  3438.                                                                                 
  3439.    if (rc == 0) {                                                               
  3440.      if (!(ddname && *ddname)) {                                                
  3441.        memcpy(ddname,(char *)tu_rtddn.ent.prm,8);                               
  3442.        *(ddname+8) = ' ';                                                       
  3443.        *(strchr(ddname,' ')) = '\0';                                            
  3444.      }                                                                          
  3445.      switch (tu_rtorg.ent.prm[0]) {                                             
  3446.        case 0x40:  return_type = SEQ; break;                                    
  3447.        case 0x02:  return_type = PDS; break;                                    
  3448.        default:    return_type = UNK; break;                                    
  3449.      }                                                                          
  3450.      if (wanted_type == SEQ && return_type != SEQ) {                            
  3451.        fprintf(stderr,"%s: not a sequential data set\n",dsname);                
  3452.      }                                                                          
  3453.      if (wanted_type == PDS && return_type != PDS) {                            
  3454.        fprintf(stderr,"%s: not a partitioned data set\n",dsname);               
  3455.      }                                                                          
  3456.      if (return_type == PDS && *member) return SEQ;                             
  3457.      else return return_type;                                                   
  3458.    }                                                                            
  3459.    else if (!try_new && nitems != 0 && stuff99.__S99ERROR == 0x1708) {          
  3460.     try_new = TRUE;                                                             
  3461.     continue;                                                                   
  3462.    }                                                                            
  3463.    else {                                                                       
  3464.      GGMdfail(rc,&stuff99);                                                     
  3465.      return UNK;                                                                
  3466.    }                                                                            
  3467.  }                                                                              
  3468. }                                                                               
  3469.                                                                                 
  3470. ./   ADD NAME=GGMCLRTX                                                          
  3471.                                                                                 
  3472.  /********************************************************************/         
  3473.  /*                                                                  */         
  3474.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3475.  /*                                                                  */         
  3476.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3477.  /*                                                                  */         
  3478.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3479.  /* including the implied warranties of merchantability and fitness, */         
  3480.  /* are expressly denied.                                            */         
  3481.  /*                                                                  */         
  3482.  /* Provided this copyright notice is included, this software may    */         
  3483.  /* be freely distributed and not offered for sale.                  */         
  3484.  /*                                                                  */         
  3485.  /* Changes or modifications may be made and used only by the maker  */         
  3486.  /* of same, and not further distributed.  Such modifications should */         
  3487.  /* be mailed to the author for consideration for addition to the    */         
  3488.  /* software and incorporation in subsequent releases.               */         
  3489.  /*                                                                  */         
  3490.  /********************************************************************/         
  3491.                                                                                 
  3492. #pragma  csect(code,  "GG@CLRTX")                                               
  3493. #pragma  csect(static,"GG$CLRTX")                                               
  3494. #include "gg.h"                                                                 
  3495.                                                                                 
  3496. /****** Clear text. **************************************************/         
  3497.                                                                                 
  3498. void                                                                            
  3499. GGMclrtx(gp,ip)                                                                 
  3500. Rstruc ggcb           *gp;                                                      
  3501. Rstruc gopherinfo     *ip;                                                      
  3502.                                                                                 
  3503. {                                                                               
  3504.  Rstruc texthdr       *thp;                                                     
  3505.  Rstruc textline      *tp1;                                                     
  3506.  Rstruc textline      *tp2;                                                     
  3507.                                                                                 
  3508.  /* If info is not specified, use main ggcb, else info's text */                
  3509.                                                                                 
  3510.  thp = (ip ? &ip->thdr : &gp->thdr);                                            
  3511.                                                                                 
  3512.  tp1=thp->first_text_line;                                                      
  3513.  while (tp1) {                                                                  
  3514.   tp2 = tp1->next;                                                              
  3515.   FREEMAIN(tp1,"text line");                                                    
  3516.   tp1 = tp2;                                                                    
  3517.  }                                                                              
  3518.                                                                                 
  3519.  thp->text_body_line    = NULL;                                                 
  3520.  thp->first_text_line   = NULL;                                                 
  3521.  thp->current_text_line = NULL;                                                 
  3522.  thp->last_text_line    = NULL;                                                 
  3523.  thp->text_line_count   = 0;                                                    
  3524.  thp->text_max_length   = 0;                                                    
  3525.  thp->text_max_tab_expanded_length   = 0;                                       
  3526.                                                                                 
  3527.  return;                                                                        
  3528.                                                                                 
  3529. }                                                                               
  3530.                                                                                 
  3531. ./   ADD NAME=GGMCONN,SSI=010D0021                                              
  3532.                                                                                 
  3533.  /********************************************************************/         
  3534.  /*                                                                  */         
  3535.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3536.  /*                                                                  */         
  3537.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3538.  /*                                                                  */         
  3539.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3540.  /* including the implied warranties of merchantability and fitness, */         
  3541.  /* are expressly denied.                                            */         
  3542.  /*                                                                  */         
  3543.  /* Provided this copyright notice is included, this software may    */         
  3544.  /* be freely distributed and not offered for sale.                  */         
  3545.  /*                                                                  */         
  3546.  /* Changes or modifications may be made and used only by the maker  */         
  3547.  /* of same, and not further distributed.  Such modifications should */         
  3548.  /* be mailed to the author for consideration for addition to the    */         
  3549.  /* software and incorporation in subsequent releases.               */         
  3550.  /*                                                                  */         
  3551.  /********************************************************************/         
  3552.                                                                                 
  3553. #pragma  csect(code,  "GG@CONN ")                                               
  3554. #pragma  csect(static,"GG$CONN ")                                               
  3555. #include "gg.h"                                                                 
  3556.                                                                                 
  3557. /****** Internet address formatter. **********************************/         
  3558.                                                                                 
  3559. static void                                                                     
  3560. format_ip_address(ia,is)                                                        
  3561. IPADDRESS   ia;                                                                 
  3562. char       *is;                                                                 
  3563. {                                                                               
  3564.  char *cp = (char *)&ia;                                                        
  3565.                                                                                 
  3566.  sprintf(is,"%d.%d.%d.%d",*cp,*(cp+1),*(cp+2),*(cp+3));                         
  3567.  return;                                                                        
  3568. }                                                                               
  3569.                                                                                 
  3570. /****** Get client hostname and IP address. **************************/         
  3571.                                                                                 
  3572. static Bool                                                                     
  3573. get_client_hostname(gp)                                                         
  3574. Rstruc ggcb        *gp;                                                         
  3575. {                                                                               
  3576.  struct hostent    *client_hp;                                                  
  3577.  int                gethostnamerc;                                              
  3578.  int                hostlen;                                                    
  3579.  int                domslen;                                                    
  3580.                                                                                 
  3581.  gethostnamerc = gethostname(gp->client_hostname,MAXHOSTNAMELEN);               
  3582.  if (gethostnamerc < 0) {                                                       
  3583.    fprintf(stderr,"GGMVS: gethostname() failed, don't know my name\n");         
  3584.    return FALSE;                                                                
  3585.  }                                                                              
  3586.                                                                                 
  3587. #ifdef APPEND_DOMAIN_NAME_TO_SELF                                               
  3588.                                                                                 
  3589.  hostlen = strlen(gp->client_hostname);                                         
  3590.  domslen = strlen(gp->mydomain);                                                
  3591.  if (hostlen <= domslen ||                                                      
  3592.     memcmp(gp->client_hostname+hostlen-domslen,gp->mydomain,domslen)) {         
  3593.    strncat(gp->client_hostname,gp->mydomain,domslen);                           
  3594.  }                                                                              
  3595.                                                                                 
  3596. #endif                                                                          
  3597.                                                                                 
  3598.  uppercase_in_place(gp->client_hostname);                                       
  3599.                                                                                 
  3600.  client_hp = gethostbyname(gp->client_hostname);                                
  3601.  if (!client_hp) {                                                              
  3602.    fprintf(stderr,                                                              
  3603.            "GGMCONN: gethostbyname(%s) failed, can't get my name\n",            
  3604.            gp->client_hostname);                                                
  3605.    return FALSE;                                                                
  3606.  }                                                                              
  3607.                                                                                 
  3608.  strcpy(gp->ggclient,gp->client_hostname);                                      
  3609.  strcpy(gp->client_hostname, client_hp->h_name);                                
  3610.  gp->client_ip_address = *(IPADDRESS *)client_hp->h_addr;                       
  3611.                                                                                 
  3612.  return TRUE ;                                                                  
  3613.                                                                                 
  3614. }                                                                               
  3615.                                                                                 
  3616. /****** Connect to news server. **************************************/         
  3617.                                                                                 
  3618. Bool                                                                            
  3619. GGMconn(gp,sp)                                                                  
  3620. Rstruc ggcb        *gp;                                                         
  3621. Rstruc connection  *sp;                                                         
  3622. {                                                                               
  3623.  char              *lp;                                                         
  3624.  char              *cp;                                                         
  3625.  struct recvstruct *R;                                                          
  3626.  struct hostent    *server_hp;                                                  
  3627.  struct sockaddr_in bindsock;       /* socket used by bind           */         
  3628.  struct sockaddr_in consock;        /* socket used by connect        */         
  3629.  int                bindsocklen;    /* size of bind socket           */         
  3630.  int                consocklen;     /* size of connect socket        */         
  3631.  int                bindrc;         /* the return code from bind     */         
  3632.  int                connrc;         /* the return code from connect  */         
  3633.  int                ip_part_1;                                                  
  3634.  int                ip_part_2;                                                  
  3635.  int                ip_part_3;                                                  
  3636.  int                ip_part_4;                                                  
  3637.  char               tempdsn[L_tmpnam];                                          
  3638.                                                                                 
  3639.  if (sp->connected_to_server) {                                                 
  3640.    GGMdisc(gp,sp);         /* Disconnect from gopher server */                  
  3641.  }                                                                              
  3642.                                                                                 
  3643.  sp->closing_connection = FALSE;                                                
  3644.  sp->buf_index          = -1;                                                   
  3645.  sp->bytes_returned     = 0;                                                    
  3646.  sp->receiving_text     = FALSE;                                                
  3647.                                                                                 
  3648.  if (!*gp->ggserver) {                                                          
  3649.    ERR1(                                                                        
  3650.   "No host server defined in Gopher menu,  Cannot make a connection."           
  3651.        );                                                                       
  3652.    return FALSE;                                                                
  3653.  }                                                                              
  3654.                                                                                 
  3655.  uppercase_in_place(gp->ggserver);                                              
  3656.                                                                                 
  3657.  /* If server is "local hack", then establish local mode,                       
  3658.   * open temporary file and return.                                             
  3659.   */                                                                            
  3660.                                                                                 
  3661.  if (!strcmp(gp->ggserver, LOCAL_HOST_FROB)) {                                  
  3662.                                                                                 
  3663.    if (gp->ginfo->port != GOPHER_PORT_NUMBER) {                                 
  3664.      ERR3("Server name %s is permitted only with port number %d.",              
  3665.           LOCAL_HOST_FROB, GOPHER_PORT_NUMBER);                                 
  3666.      return FALSE;                                                              
  3667.    }                                                                            
  3668.                                                                                 
  3669.    GETMAIN(gp->recvp, struct recvstruct, 1, "local recv struct");               
  3670.    if (!gp->recvp) {                                                            
  3671.      CRIT1("Can't get memory for local host struct");                           
  3672.      return FALSE;                                                              
  3673.    }                                                                            
  3674.    R = gp->recvp;                                                               
  3675.    memset(R, 0, sizeof(struct recvstruct));                                     
  3676.                                                                                 
  3677.    R->myport   = gp->myport;                                                    
  3678.    R->mytelnet = gp->mytelnet;                                                  
  3679.    R->mydomain = gp->mydomain;                                                  
  3680.                                                                                 
  3681.    if (!tmpnam(tempdsn)) {                                                      
  3682.      CRIT1("Can't create temporary file for local access");                     
  3683.      return FALSE;                                                              
  3684.    }                                                                            
  3685.                                                                                 
  3686.    /* Create temporary file for writing and reading. */                         
  3687.                                                                                 
  3688.    R->outfp = fopen(tempdsn,"w+,type=memory");                                  
  3689.    if (!R->outfp) {                                                             
  3690.      perror(tempdsn);                                                           
  3691.      CRIT1("Can't open temporary file for local access");                       
  3692.      return FALSE;                                                              
  3693.    }                                                                            
  3694.                                                                                 
  3695.    sp->connected_to_server = TRUE;                                              
  3696.    sp->time_to_go_home     = FALSE;                                             
  3697.    sp->connection_broken   = FALSE;                                             
  3698.                                                                                 
  3699.    GGMesrvr(gp,sp);                                                             
  3700.                                                                                 
  3701.    return TRUE;                                                                 
  3702.  }                                                                              
  3703.                                                                                 
  3704.  /* Disallow network connections if started up in local mode. */                
  3705.                                                                                 
  3706.  if (gp->local_mode) {                                                          
  3707.    ERR1("Network connections are not allowed in local mode.");                  
  3708.    return FALSE;                                                                
  3709.  }                                                                              
  3710.                                                                                 
  3711.  /* Determine the local path name. Do only if making net conn. */               
  3712.                                                                                 
  3713.  if (!*gp->client_hostname) {                                                   
  3714.                                                                                 
  3715.    if (!get_client_hostname(gp)) return FALSE;                                  
  3716.                                                                                 
  3717.  }                                                                              
  3718.                                                                                 
  3719.  /* Get server name and address.  */                                            
  3720.                                                                                 
  3721.  if (strchr(gp->ggserver,'.') &&                                                
  3722.      gp->ggserver[strspn(gp->ggserver,".0123456789")] == '\0') {                
  3723.    ip_part_1 = ip_part_2 = ip_part_3 = ip_part_4 = 32767;                       
  3724.    strcpy(gp->server_hostname, gp->ggserver);                                   
  3725.    sscanf(gp->ggserver,"%d.%d.%d.%d",&ip_part_1,                                
  3726.                                      &ip_part_2,                                
  3727.                                      &ip_part_3,                                
  3728.                                      &ip_part_4);                               
  3729.    if (ip_part_1 > 255 ||                                                       
  3730.        ip_part_2 > 255 ||                                                       
  3731.        ip_part_3 > 255 ||                                                       
  3732.        ip_part_4 > 255) {                                                       
  3733.      ERR2("Syntax error in server network address: %s", gp->ggserver);          
  3734.      return FALSE;                                                              
  3735.    }                                                                            
  3736.    gp->server_ip_address = (IPADDRESS) ((ip_part_1 << 24) +                     
  3737.                                         (ip_part_2 << 16) +                     
  3738.                                         (ip_part_3 <<  8) +                     
  3739.                                         (ip_part_4      ));                     
  3740.  }                                                                              
  3741.  else {                                                                         
  3742.    server_hp = gethostbyname(gp->ggserver);                                     
  3743.    if (!server_hp) {                                                            
  3744.      ERR2(                                                                      
  3745. "Unknown host %s - gethostbyname() could not resolve the server name.",         
  3746.           gp->ggserver);                                                        
  3747.      return FALSE;                                                              
  3748.    }                                                                            
  3749.    strcpy(gp->server_hostname, server_hp->h_name);                              
  3750.    gp->server_ip_address = *(IPADDRESS *)server_hp->h_addr;                     
  3751.  }                                                                              
  3752.                                                                                 
  3753.  format_ip_address(gp->server_ip_address, gp->server_ip_addrstr);               
  3754.  format_ip_address(gp->client_ip_address, gp->client_ip_addrstr);               
  3755.                                                                                 
  3756.  (void)GGMivput(gp,"GGSERVER ",gp->ggserver,-1);                                
  3757.  (void)GGMivput(gp,"GGSERVIP ",gp->server_ip_addrstr,-1);                       
  3758.  (void)GGMivput(gp,"GGCLIENT ",gp->ggclient,-1);                                
  3759.  (void)GGMivput(gp,"GGCLIEIP ",gp->client_ip_addrstr,-1);                       
  3760.                                                                                 
  3761.  consock.sin_family       = AF_INET;                                            
  3762.  consock.sin_port         = htons(gp->ginfo->port);                             
  3763.  consock.sin_addr.s_addr  = gp->server_ip_address;                              
  3764.                                                                                 
  3765.  bindsock.sin_family      = AF_INET;                                            
  3766.  bindsock.sin_port        = 0;                                                  
  3767. #ifdef SNSTCPIP                                                                 
  3768.  bindsock.sin_addr.s_addr = INADDR_ANY;                                         
  3769. #else                                                                           
  3770.  bindsock.sin_addr.s_addr = gp->client_ip_address;                              
  3771. #endif                                                                          
  3772.                                                                                 
  3773.  sp->ns = socket(AF_INET, SOCK_STREAM, 0);                                      
  3774.  if (sp->ns < 0) {                                                              
  3775.    REPORT_TCP_ERROR(gp->ggserver);                                              
  3776.    ERR2("TCP/IP error: socket() failed to make socket for server %s.",          
  3777.         gp->ggserver);                                                          
  3778.    return FALSE;                                                                
  3779.  }                                                                              
  3780.                                                                                 
  3781.  bindsocklen = sizeof(bindsock);                                                
  3782.  bindrc = Bind(sp->ns, &bindsock, bindsocklen);                                 
  3783.  if (bindrc < 0) {                                                              
  3784.    REPORT_TCP_ERROR(gp->ggserver);                                              
  3785.    ERR2("TCP/IP error: bind() failed to bind socket for server %s.",            
  3786.         gp->ggserver);                                                          
  3787.    return FALSE;                                                                
  3788.  }                                                                              
  3789.                                                                                 
  3790.  (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                      
  3791.  (void)GGMispf(gp,"DISPLAY PANEL(GGMLCONN)");                                   
  3792.                                                                                 
  3793.  if (gp->debug_file) {                                                          
  3794.    fprintf(gp->debug_file,                                                      
  3795.            "Client %s (%s) connecting to GOPHER server on %s (%s)\n",           
  3796.            gp->client_hostname,                                                 
  3797.            gp->client_ip_addrstr,                                               
  3798.            gp->server_hostname,                                                 
  3799.            gp->server_ip_addrstr);                                              
  3800.  }                                                                              
  3801.                                                                                 
  3802.  consocklen = sizeof(consock);                                                  
  3803.  connrc = Connect(sp->ns, &consock, consocklen);                                
  3804.                                                                                 
  3805.  if (connrc < 0) {                                                              
  3806.    REPORT_TCP_ERROR(gp->ggserver);                                              
  3807.    ERR2("TCP/IP failure: connect() failed to connect to server %s.",            
  3808.         gp->ggserver);                                                          
  3809.    return FALSE;                                                                
  3810.  }                                                                              
  3811.                                                                                 
  3812.  sp->connected_to_server = TRUE;                                                
  3813.  sp->time_to_go_home     = FALSE;                                               
  3814.  sp->connection_broken   = FALSE;                                               
  3815.  sp->server_has_something_pending = TRUE;                                       
  3816.  sp->dont_read           = FALSE;                                               
  3817.                                                                                 
  3818.  /* Clean up any stray responses from server. */                                
  3819.                                                                                 
  3820.  GGMesrvr(gp,sp);                         /* End server read */                 
  3821.                                                                                 
  3822.  return TRUE;                                                                   
  3823.                                                                                 
  3824. }                                                                               
  3825.                                                                                 
  3826. ./   ADD NAME=GGMCSO,SSI=01000026                                               
  3827.                                                                                 
  3828.  /********************************************************************/         
  3829.  /*                                                                  */         
  3830.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3831.  /*                                                                  */         
  3832.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3833.  /*                                                                  */         
  3834.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3835.  /* including the implied warranties of merchantability and fitness, */         
  3836.  /* are expressly denied.                                            */         
  3837.  /*                                                                  */         
  3838.  /* Provided this copyright notice is included, this software may    */         
  3839.  /* be freely distributed and not offered for sale.                  */         
  3840.  /*                                                                  */         
  3841.  /* Changes or modifications may be made and used only by the maker  */         
  3842.  /* of same, and not further distributed.  Such modifications should */         
  3843.  /* be mailed to the author for consideration for addition to the    */         
  3844.  /* software and incorporation in subsequent releases.               */         
  3845.  /*                                                                  */         
  3846.  /********************************************************************/         
  3847.                                                                                 
  3848. #pragma  csect(code,  "GG@CSO")                                                 
  3849. #pragma  csect(static,"GG$CSO")                                                 
  3850. #include "gg.h"                                                                 
  3851.                                                                                 
  3852. /****** Gopher CSO interface. ************************************/             
  3853.                                                                                 
  3854. Bool                                                                            
  3855. GGMcso(gp,ip,as_file)                                                           
  3856. Rstruc ggcb        *gp;                                                         
  3857. Rstruc gopherinfo  *ip;                                                         
  3858. Fool                as_file;        /* ignored */                               
  3859. {                                                                               
  3860.  Rstruc connection *sp;                                                         
  3861.  char              *lp;                                                         
  3862.  Bool               got_some;                                                   
  3863.  char               ggcsoq[256];                                                
  3864.  int                e_index_i;                                                  
  3865.  char               e_index_c[10];                                              
  3866.  char               sep[80] = "--------------------";                           
  3867.                                                                                 
  3868.  sp = &gp->gopher_connection;                                                   
  3869.                                                                                 
  3870.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  3871.                                                                                 
  3872.  strcpy(ggcsoq,"");                                                             
  3873.                                                                                 
  3874.  GGMispf(gp,"VGET (GGCSOQ) PROFILE");                                           
  3875.                                                                                 
  3876.  if (GGMdispl(gp,"GGMPCSO ") > 0) return FALSE;                                 
  3877.                                                                                 
  3878.  GGMivget(gp,"GGCSOQ ",ggcsoq, sizeof(ggcsoq));                                 
  3879.                                                                                 
  3880.  /***** set up query command to server ****** start ******************/         
  3881.                                                                                 
  3882.  strcpy(gp->gopher_command,"query ");                                           
  3883.  if (!*ip->path)                                                                
  3884.      strcpy(gp->gopher_command + 6, ggcsoq);                                    
  3885.  else                                                                           
  3886.      sprintf(gp->gopher_command + 6,"%s\t%s",ip->path,ggcsoq);                  
  3887.  strcat(gp->gopher_command," return all");                                      
  3888.                                                                                 
  3889.  /***** set up query command to server ****** end   ******************/         
  3890.                                                                                 
  3891.  gp->ginfo = ip;                                                                
  3892.                                                                                 
  3893.  if (!GGMconn(gp,sp)) return FALSE;   /* Connect to CSO server */               
  3894.                                                                                 
  3895.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  3896.                                                                                 
  3897.  GGMclrtx(gp,ip);                  /* Clear text */                             
  3898.                                                                                 
  3899.  sp->receiving_text = TRUE;                                                     
  3900.  got_some = FALSE;                                                              
  3901.  e_index_i = 2;                                                                 
  3902.  sprintf(e_index_c,":%u:",e_index_i);                                           
  3903.  do {                                                                           
  3904.    if (GGMgsrvl(gp,sp,&lp,FALSE)) {        /* Get server line */                
  3905.      if (lp) {                                                                  
  3906.        if (strstr(lp,e_index_c) != NULL) { /* if new entry */                   
  3907.          (void)GGMouttx(gp,sep,ip);        /* Output separator */               
  3908.          ++e_index_i;                      /* Increment index  */               
  3909.          sprintf(e_index_c,":%u:",e_index_i);                                   
  3910.        }                                                                        
  3911.        got_some = TRUE;                                                         
  3912.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  3913.        if (lp[0] != '-' && strncmp(lp,"200",3) >= 0) break;                     
  3914.      }                                                                          
  3915.    }                                                                            
  3916.  } while (lp);                            /* until no more lines */             
  3917.                                                                                 
  3918.  if (!got_some) {                                                               
  3919.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  3920.    return FALSE;                                                                
  3921.  }                                                                              
  3922.                                                                                 
  3923.  /* Send quit command        */                                                 
  3924.                                                                                 
  3925.  sp->receiving_text = FALSE;                                                    
  3926.                                                                                 
  3927.  strcpy(gp->gopher_command,"quit");                                             
  3928.                                                                                 
  3929.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  3930.                                                                                 
  3931.  /* Read Bye message         */                                                 
  3932.                                                                                 
  3933.  sp->receiving_text = TRUE;                                                     
  3934.                                                                                 
  3935.  (void)GGMgsrvl(gp,sp,&lp,FALSE);         /* Get server line */                 
  3936.                                                                                 
  3937.  if (sp->connected_to_server) {                                                 
  3938.    (void)GGMdisc(gp,sp);   /* Disconnect from CSO server */                     
  3939.  }                                                                              
  3940.                                                                                 
  3941.  GGMvtx(gp,ip,as_file);  /* display text from CSO server */                     
  3942.                                                                                 
  3943.  return TRUE;                                                                   
  3944.                                                                                 
  3945. }                                                                               
  3946.                                                                                 
  3947. ./   ADD NAME=GGMDBM,SSI=01050050                                               
  3948.                                                                                 
  3949.  /********************************************************************/         
  3950.  /*                                                                  */         
  3951.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3952.  /*                                                                  */         
  3953.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  3954.  /*                                                                  */         
  3955.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3956.  /* including the implied warranties of merchantability and fitness, */         
  3957.  /* are expressly denied.                                            */         
  3958.  /*                                                                  */         
  3959.  /* Provided this copyright notice is included, this software may    */         
  3960.  /* be freely distributed and not offered for sale.                  */         
  3961.  /*                                                                  */         
  3962.  /* Changes or modifications may be made and used only by the maker  */         
  3963.  /* of same, and not further distributed.  Such modifications should */         
  3964.  /* be mailed to the author for consideration for addition to the    */         
  3965.  /* software and incorporation in subsequent releases.               */         
  3966.  /*                                                                  */         
  3967.  /********************************************************************/         
  3968.                                                                                 
  3969. #pragma  csect(code,  "GG@DBM  ")                                               
  3970. #pragma  csect(static,"GG$DBM  ")                                               
  3971. #include "gg.h"                                                                 
  3972.                                                                                 
  3973. /****** Delete a bookmark from a bookmark data set. ******************/         
  3974.                                                                                 
  3975. Bool                                                                            
  3976. GGMdbm(gp,ip)                                                                   
  3977. Rstruc ggcb         *gp;                                                        
  3978. Rstruc gopherinfo   *ip;                                                        
  3979. {                                                                               
  3980.  FILE               *xfp;                                                       
  3981.  char               *bufptr;                                                    
  3982.  char                test   [  6];                                              
  3983.  char                dsname [129];                                              
  3984.  char                buffer [RBUFSIZE];                                         
  3985.                                                                                 
  3986.  if (!*ip->bmds) {                                                              
  3987.    WARN1("Delete not possible.  This entry is not from a bookmark.");           
  3988.    return FALSE;                                                                
  3989.  }                                                                              
  3990.                                                                                 
  3991.  GGMivput(gp,"GGMDBMDS ",ip->bmds,-1);                                          
  3992.  GGMivput(gp,"GGMDBMSU ",ip->desc,-1);                                          
  3993.                                                                                 
  3994.  (void)GGMispf(gp,"ADDPOP");                                                    
  3995.                                                                                 
  3996.  if (GGMdispl(gp,"GGMPDBM ") > 0) {                                             
  3997.    WARN1("Deletion cancelled, because you pressed END.");                       
  3998.    (void)GGMispf(gp,"REMPOP");                                                  
  3999.    return FALSE;                                                                
  4000.  }                                                                              
  4001.                                                                                 
  4002.  (void)GGMispf(gp,"REMPOP");                                                    
  4003.                                                                                 
  4004.  sprintf(dsname,"'%s'",ip->bmds);                                               
  4005.  xfp = fopen(dsname,"r");                                                       
  4006.  if (!xfp) {                                                                    
  4007.    perror(dsname);                                                              
  4008.    ERR2("Cannot access bookmark data set %s.",dsname);                          
  4009.    return FALSE;                                                                
  4010.  }                                                                              
  4011.                                                                                 
  4012.                                                                                 
  4013.  for (;;) {                                                                     
  4014.    *buffer = '\0';                                                              
  4015.    fgets(buffer,sizeof(buffer),xfp);                                            
  4016.    if (ferror(xfp)) {                                                           
  4017.      ERR2("Error reading bookmark data set %s.",dsname);                        
  4018.      break;                                                                     
  4019.    }                                                                            
  4020.    if (feof(xfp)) break;                                                        
  4021.    if ((bufptr=strchr(buffer,'\n'))) *bufptr = '\0';                            
  4022.    bufptr = skip_whitespace(buffer);                                            
  4023.    memset(test,0,sizeof(test));                                                 
  4024.    memcpy(test,bufptr,5);                                                       
  4025.    uppercase_in_place(test);                                                    
  4026.                                                                                 
  4027.    /*                                                                           
  4028.    if      (EQUAL(test,"TYPE="))                                                
  4029.    else if (EQUAL(test,"NAME="))                                                
  4030.    else if (EQUAL(test,"PATH="))                                                
  4031.    else if (EQUAL(test,"HOST="))                                                
  4032.    else if (EQUAL(test,"PORT="))                                                
  4033.    else if (EQUAL(test,"END"  ))                                                
  4034.                                                                                 
  4035.    */                                                                           
  4036.                                                                                 
  4037.  }                                                                              
  4038.                                                                                 
  4039.  (void)fclose(xfp);                                                             
  4040.                                                                                 
  4041.  ERR1("Bookmark deletion is not yet supported, sorry.");                        
  4042.  return FALSE;                                                                  
  4043.                                                                                 
  4044. }                                                                               
  4045.                                                                                 
  4046. ./   ADD NAME=GGMDFAIL                                                          
  4047.                                                                                 
  4048.  /********************************************************************/         
  4049.  /*                                                                  */         
  4050.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4051.  /*                                                                  */         
  4052.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4053.  /*                                                                  */         
  4054.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4055.  /* including the implied warranties of merchantability and fitness, */         
  4056.  /* are expressly denied.                                            */         
  4057.  /*                                                                  */         
  4058.  /* Provided this copyright notice is included, this software may    */         
  4059.  /* be freely distributed and not offered for sale.                  */         
  4060.  /*                                                                  */         
  4061.  /* Changes or modifications may be made and used only by the maker  */         
  4062.  /* of same, and not further distributed.  Such modifications should */         
  4063.  /* be mailed to the author for consideration for addition to the    */         
  4064.  /* software and incorporation in subsequent releases.               */         
  4065.  /*                                                                  */         
  4066.  /********************************************************************/         
  4067.                                                                                 
  4068. #pragma  csect(code,  "GG@DFAIL")                                               
  4069. #pragma  csect(static,"GG$DFAIL")                                               
  4070. #include "gg.h"                                                                 
  4071.                                                                                 
  4072. /****** Retrieve allocation failure messages. ************************/         
  4073.                                                                                 
  4074. void                                                                            
  4075. GGMdfail(rc,p99)                                                                
  4076. int            rc;                                                              
  4077. __S99parms    *p99;                                                             
  4078. {                                                                               
  4079.  int           zero = 0;                                                        
  4080.  unsigned int  dfid = 0x40320000;                                               
  4081.  struct {                                                                       
  4082.          short first_level_msg_len;                                             
  4083.          short first_level_msg_offset;                                          
  4084.          char  first_level_msg[251];                                            
  4085.          short second_level_msg_len;                                            
  4086.          short second_level_msg_offset;                                         
  4087.          char  second_level_msg[251];                                           
  4088.         }      dfbuffer;                                                        
  4089.                                                                                 
  4090.  static int (*ikjeff18_pointer)() = NULL;                                       
  4091.                                                                                 
  4092. #ifndef FETCH                                                                   
  4093.  extern int *ikjeff18();                                                        
  4094. #endif                                                                          
  4095.                                                                                 
  4096.  if (!ikjeff18_pointer) {                                                       
  4097. #ifdef FETCH                                                                    
  4098.    ikjeff18_pointer = (int (*)())fetch("IKJEFF18");                             
  4099. #else                                                                           
  4100.    ikjeff18_pointer = (int (*)())ikjeff18;                                      
  4101. #endif                                                                          
  4102.  }                                                                              
  4103.                                                                                 
  4104.  dfbuffer.first_level_msg_len = 4;                                              
  4105.  dfbuffer.second_level_msg_len = 4;                                             
  4106.                                                                                 
  4107.  if (ikjeff18_pointer) {                                                        
  4108.    if ((*ikjeff18_pointer)(p99,&rc,&zero,&dfid,&zero,&dfbuffer)) {              
  4109.      fprintf(stderr,"IKJEFF18 returned a nonzero return code\n");               
  4110.    }                                                                            
  4111.    if (dfbuffer.first_level_msg_len > 0) {                                      
  4112.      fprintf(stderr,"%*.*s\n",                                                  
  4113.                     dfbuffer.first_level_msg_len-4,                             
  4114.                     dfbuffer.first_level_msg_len-4,                             
  4115.                     dfbuffer.first_level_msg);                                  
  4116.    }                                                                            
  4117.    if (dfbuffer.second_level_msg_len > 0) {                                     
  4118.      fprintf(stderr,"%*.*s\n",                                                  
  4119.                     dfbuffer.second_level_msg_len-4,                            
  4120.                     dfbuffer.second_level_msg_len-4,                            
  4121.                     dfbuffer.second_level_msg);                                 
  4122.    }                                                                            
  4123.  }                                                                              
  4124.  else {                                                                         
  4125. #ifdef FETCH                                                                    
  4126.    fprintf(stderr,"GGMVS: Cannot fetch IKJEFF18\n");                            
  4127. #else                                                                           
  4128.    fprintf(stderr,"Cannot call IKJEFF18, not linked with GGMVS\n");             
  4129. #endif                                                                          
  4130.  }                                                                              
  4131.  return;                                                                        
  4132. }                                                                               
  4133.                                                                                 
  4134. ./   ADD NAME=GGMDIR,SSI=011A0056                                               
  4135.                                                                                 
  4136.  /********************************************************************/         
  4137.  /*                                                                  */         
  4138.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4139.  /*                                                                  */         
  4140.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4141.  /*                                                                  */         
  4142.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4143.  /* including the implied warranties of merchantability and fitness, */         
  4144.  /* are expressly denied.                                            */         
  4145.  /*                                                                  */         
  4146.  /* Provided this copyright notice is included, this software may    */         
  4147.  /* be freely distributed and not offered for sale.                  */         
  4148.  /*                                                                  */         
  4149.  /* Changes or modifications may be made and used only by the maker  */         
  4150.  /* of same, and not further distributed.  Such modifications should */         
  4151.  /* be mailed to the author for consideration for addition to the    */         
  4152.  /* software and incorporation in subsequent releases.               */         
  4153.  /*                                                                  */         
  4154.  /********************************************************************/         
  4155.                                                                                 
  4156. #pragma  csect(code,  "GG@DIR  ")                                               
  4157. #pragma  csect(static,"GG$DIR  ")                                               
  4158. #include "gg.h"                                                                 
  4159.                                                                                 
  4160. /*********************************************************************/         
  4161.                                                                                 
  4162. static Bool                                                                     
  4163. valid_code(c)                                                                   
  4164. char       c;                                                                   
  4165. {                                                                               
  4166.                                                                                 
  4167.  switch (c) {                                                                   
  4168.    case GOPHER_FILE:                                                            
  4169.    case GOPHER_DIRECTORY:                                                       
  4170.    case GOPHER_TELNET:                                                          
  4171.    case GOPHER_TN3270:                                                          
  4172.    case GOPHER_WAIS:                                                            
  4173.    case GOPHER_WHOIS:                                                           
  4174.    case GOPHER_CSO:                                                             
  4175.                            return TRUE;                                         
  4176.    default:                return FALSE;                                        
  4177.   }                                                                             
  4178.                                                                                 
  4179. }                                                                               
  4180.                                                                                 
  4181. /*********************************************************************/         
  4182.                                                                                 
  4183. static Bool                                                                     
  4184. process_s_selection(gp,ip)                                                      
  4185. Rstruc ggcb           *gp;                                                      
  4186. Rstruc gopherinfo     *ip;                                                      
  4187. {                                                                               
  4188.                                                                                 
  4189.  GGMgofor(gp,ip,FALSE);                                                         
  4190.                                                                                 
  4191.  return TRUE;                                                                   
  4192. }                                                                               
  4193.                                                                                 
  4194. /*********************************************************************/         
  4195.                                                                                 
  4196. static Bool                                                                     
  4197. process_i_selection(gp,ip)                                                      
  4198. Rstruc ggcb           *gp;                                                      
  4199. Rstruc gopherinfo     *ip;                                                      
  4200. {                                                                               
  4201.                                                                                 
  4202.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  4203.                                                                                 
  4204.  GGMvtx(gp,NULL,TRUE);                                                          
  4205.                                                                                 
  4206.  return TRUE;                                                                   
  4207. }                                                                               
  4208.                                                                                 
  4209. /*********************************************************************/         
  4210.                                                                                 
  4211. static Bool                                                                     
  4212. process_b_selection(gp,ip)                                                      
  4213. Rstruc ggcb           *gp;                                                      
  4214. Rstruc gopherinfo     *ip;                                                      
  4215. {                                                                               
  4216.                                                                                 
  4217.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  4218.                                                                                 
  4219.  gp->extract_file = NULL;                                                       
  4220.                                                                                 
  4221.  GGMxtx(gp,ip,BOOKMARK_IT);                                                     
  4222.                                                                                 
  4223.  return TRUE;                                                                   
  4224. }                                                                               
  4225.                                                                                 
  4226. /*********************************************************************/         
  4227.                                                                                 
  4228. static Bool                                                                     
  4229. process_d_selection(gp,ip)                                                      
  4230. Rstruc ggcb           *gp;                                                      
  4231. Rstruc gopherinfo     *ip;                                                      
  4232. {                                                                               
  4233.                                                                                 
  4234.  return GGMdbm(gp,ip);                                                          
  4235. }                                                                               
  4236.                                                                                 
  4237. /*********************************************************************/         
  4238.                                                                                 
  4239. static Bool                                                                     
  4240. process_e_selection(gp,ip)                                                      
  4241. Rstruc ggcb           *gp;                                                      
  4242. Rstruc gopherinfo     *ip;                                                      
  4243. {                                                                               
  4244.                                                                                 
  4245.  gp->extract_file = NULL;                                                       
  4246.                                                                                 
  4247.  if (ip->thdr.first_text_line) {                                                
  4248.    GGMxtx(gp,ip,EXTRACT_IT);                                                    
  4249.    return TRUE;                                                                 
  4250.  }                                                                              
  4251.  else {                                                                         
  4252.    ERR1("Extract must be preceded by Select.");                                 
  4253.    return FALSE;                                                                
  4254.  }                                                                              
  4255. }                                                                               
  4256.                                                                                 
  4257. /*********************************************************************/         
  4258.                                                                                 
  4259. static Bool                                                                     
  4260. process_p_selection(gp,ip)                                                      
  4261. Rstruc ggcb           *gp;                                                      
  4262. Rstruc gopherinfo     *ip;                                                      
  4263. {                                                                               
  4264.                                                                                 
  4265.  gp->extract_file = NULL;                                                       
  4266.                                                                                 
  4267.  if (ip->thdr.first_text_line) {                                                
  4268.    GGMxtx(gp,ip,PRINT_IT);                                                      
  4269.    return TRUE;                                                                 
  4270.  }                                                                              
  4271.  else {                                                                         
  4272.    ERR1("Print must be preceded by Select.");                                   
  4273.    return FALSE;                                                                
  4274.  }                                                                              
  4275. }                                                                               
  4276.                                                                                 
  4277. /*********************************************************************/         
  4278.                                                                                 
  4279. static Bool                                                                     
  4280. process_q_selection(gp,ip)                                                      
  4281. Rstruc ggcb           *gp;                                                      
  4282. Rstruc gopherinfo     *ip;                                                      
  4283. {                                                                               
  4284.                                                                                 
  4285.  GGMgofor(gp,ip,TRUE);                                                          
  4286.                                                                                 
  4287.  return TRUE;                                                                   
  4288. }                                                                               
  4289.                                                                                 
  4290. /*********************************************************************/         
  4291.                                                                                 
  4292. static Bool                                                                     
  4293. display_dynamic_area(gp,ip,infoarray,entrycount)                                
  4294. Rstruc ggcb           *gp;                                                      
  4295. Rstruc gopherinfo     *ip;                                                      
  4296. Rstruc gopherinfo     *infoarray;                                               
  4297. int                    entrycount;                                              
  4298. {                                                                               
  4299.  struct gopherinfo    *iap;                                                     
  4300.  int                   depth;                                                   
  4301.  int                   ggglvl;                                                  
  4302.  int                   dynsize;                                                 
  4303.  int                   topitem;                                                 
  4304.  int                   bottomitem;                                              
  4305.  int                   last_item_selected;                                      
  4306.  int                   dti;                                                     
  4307.  int                   gii;                                                     
  4308.  int                   l;                                                       
  4309.  int                   prc;                                                     
  4310.  int                   command_index;                                           
  4311.  int                   zscrolln;                                                
  4312.  int                   leftcol;                                                 
  4313.  int                   maxcol;                                                  
  4314.  int                   menucursor;                                              
  4315.  Bool                  selection_processed_ok;                                  
  4316.  Bool                  command_processed_ok;                                    
  4317.  Bool                  is_max;                                                  
  4318.  Bool                  is_csr;                                                  
  4319.  char                 *gggdyna;                                                 
  4320.  char                 *rowp;                                                    
  4321.  char                 *cp;                                                      
  4322.  char                  gggcmd     [72];                                         
  4323.  char                  zverb       [9];                                         
  4324.  char                  zscrolla    [9];                                         
  4325.  char                  command    [COMMANDSIZE];                                
  4326.  char                  ggghead    [81];                                         
  4327.  char                  gggcsr     [12];                                         
  4328.  char                  rowmessage [81];                                         
  4329.                                                                                 
  4330.  /* Get depth of dynamic area (number of rows to display on screen) */          
  4331.                                                                                 
  4332.  (void)GGMispf(gp,                                                              
  4333.        "PQUERY PANEL(GGMDIR) AREANAME(GGGDYNA) DEPTH(GGGDEPTH)");               
  4334.  if (gp->ispfrc != 0) return FALSE;                                             
  4335.  depth = GGMiget(gp,"GGGDEPTH ");                                               
  4336.                                                                                 
  4337.  /* Get storage for ISPF dynamic area variable to be constructed. */            
  4338.                                                                                 
  4339.  dynsize = 80*depth;                                                            
  4340.  GETMAIN(gggdyna, char, dynsize+1, "GGGDYNA buffer");                           
  4341.  if (!gggdyna) return FALSE;                                                    
  4342.                                                                                 
  4343.  /* Loop displaying the panel until END pressed. */                             
  4344.                                                                                 
  4345.  topitem = 0;                                                                   
  4346.  leftcol = 0;                                                                   
  4347.  menucursor = 0;                                                                
  4348.  last_item_selected = -1;                                                       
  4349.  strcpy(gggcmd,"");                                                             
  4350.                                                                                 
  4351.  maxcol = 0;                                                                    
  4352.  for (gii = 0; gii < entrycount; gii++) {                                       
  4353.    l = strlen(infoarray[gii].desc);                                             
  4354.    if (maxcol < l) maxcol = l;                                                  
  4355.  }                                                                              
  4356.                                                                                 
  4357.  do {                                                                           
  4358.                                                                                 
  4359.  /* Fill in the dynamic area with rows, one for each gopher item. */            
  4360.                                                                                 
  4361.    memset(gggdyna,' ',dynsize);                                                 
  4362.    menucursor = 0;                                                              
  4363.                                                                                 
  4364.    for (dti = 0,       gii = topitem,     rowp = gggdyna;                       
  4365.         dti < depth && gii < entrycount;                                        
  4366.         dti++,         gii++,             rowp += 80) {                         
  4367.      iap = &infoarray[gii];                                                     
  4368.      if (gp->autocursor && gii == last_item_selected) {                         
  4369.        menucursor = rowp + 2 - gggdyna;                                         
  4370.      }                                                                          
  4371.      rowp[ 0] = DATAIN_HIGH;             /* selection code attribute */         
  4372.      rowp[ 1] = ' ';                     /* selection code field     */         
  4373.      rowp[ 2] = DATAOUT_GREEN;           /* icon attribute           */         
  4374.      memcpy(&rowp[ 3],GGMtype(iap->type),9);                                    
  4375.      rowp[12] = DATAOUT_HIGH;            /* description attribute    */         
  4376.      l = strlen(iap->desc) - leftcol;                                           
  4377.      if (l > 0) {                                                               
  4378.        memcpy(&rowp[13], iap->desc + leftcol, l > 67 ? 67 : l);                 
  4379.      }                                                                          
  4380.    }                                                                            
  4381.                                                                                 
  4382.    if (rowp < gggdyna + dynsize) {                                              
  4383.      rowp[0] = DATAOUT_HIGH;                                                    
  4384.      memset(&rowp[1], '-',79);                                                  
  4385.    }                                                                            
  4386.                                                                                 
  4387.    bottomitem = gii - 1;                                                        
  4388.                                                                                 
  4389.    if (topitem > bottomitem) strcpy(rowmessage,"");                             
  4390.    else sprintf(rowmessage, " %d-%d of %d",                                     
  4391.                        topitem + 1, bottomitem + 1, entrycount);                
  4392.                                                                                 
  4393.    memset(ggghead,' ',79);                                                      
  4394.    ggghead[79] = '\0';                                                          
  4395.    strcpy(ggghead,"GOPHER - ");                                                 
  4396.    strncpy(ggghead+9,ip->desc,70);                                              
  4397.    *strchr(ggghead,'\0') = ' ';                                                 
  4398.    memcpy(ggghead+79-strlen(rowmessage),rowmessage,strlen(rowmessage));         
  4399.                                                                                 
  4400.    if (menucursor > 0) {                                                        
  4401.      sprintf(gggcsr,"%d",menucursor);                                           
  4402.      (void)GGMivput(gp,"GGGCSR ", gggcsr, -1);                                  
  4403.    }                                                                            
  4404.    else {                                                                       
  4405.      (void)GGMivput(gp,"GGGCSR ", "0", 1);                                      
  4406.    }                                                                            
  4407.                                                                                 
  4408.    (void)GGMivput(gp,"GGGHEAD ",ggghead,79);                                    
  4409.    (void)GGMivput(gp,"GGGDYNA ",gggdyna, dynsize);                              
  4410.    (void)GGMivput(gp,"GGGCMD " ,gggcmd,  -1);                                   
  4411.                                                                                 
  4412.    prc = GGMdispl(gp,"GGMDIR  ");                                               
  4413.    if (prc > 8) break;                                                          
  4414.                                                                                 
  4415.    (void)GGMivget(gp,"GGGDYNA " , gggdyna,  dynsize);                           
  4416.    (void)GGMivget(gp,"ZVERB "   , zverb,    sizeof(zverb));                     
  4417.    (void)GGMivget(gp,"ZSCROLLA ", zscrolla, sizeof(zscrolla));                  
  4418.    zscrolln = GGMiget(gp,"ZSCROLLN ");                                          
  4419.    ggglvl   = GGMiget(gp,"GGGLVL ");                                            
  4420.    last_item_selected = -1;                                                     
  4421.                                                                                 
  4422.    /* Process selections. */                                                    
  4423.                                                                                 
  4424.    for (gii = topitem,         rowp = gggdyna;                                  
  4425.         gii <= bottomitem;                                                      
  4426.         gii++,                 rowp += 80) {                                    
  4427.      iap = &infoarray[gii];                                                     
  4428.      switch (toupper(rowp[1])) {                                                
  4429.        case ' ':  continue;                                                     
  4430.        case 'S':  selection_processed_ok = process_s_selection(gp,iap);         
  4431.                   break;                                                        
  4432.        case 'E':  selection_processed_ok = process_e_selection(gp,iap);         
  4433.                   break;                                                        
  4434.        case 'P':  selection_processed_ok = process_p_selection(gp,iap);         
  4435.                   break;                                                        
  4436.        case 'Q':  selection_processed_ok = process_q_selection(gp,iap);         
  4437.                   break;                                                        
  4438.        case 'I':  selection_processed_ok = process_i_selection(gp,iap);         
  4439.                   break;                                                        
  4440.        case 'B':  selection_processed_ok = process_b_selection(gp,iap);         
  4441.                   break;                                                        
  4442.    /*                                                                           
  4443.     *  case 'D':  selection_processed_ok = process_d_selection(gp,iap);         
  4444.     *             break;                                                        
  4445.     */                                                                          
  4446.        default:                                                                 
  4447.         ERR1("Unknown selection code.  Type one of the listed codes.");         
  4448.                   selection_processed_ok = FALSE;                               
  4449.                   break;                                                        
  4450.      }                                                                          
  4451.      if (selection_processed_ok) last_item_selected = gii;                      
  4452.      if (gp->quit) break;                                                       
  4453.    }                                                                            
  4454.                                                                                 
  4455.    /* Process command if any. */                                                
  4456.                                                                                 
  4457.    strcpy(gggcmd,"");                                                           
  4458.                                                                                 
  4459.    (void)GGMivget(gp,"GGGCMD ",gggcmd,sizeof(gggcmd));                          
  4460.                                                                                 
  4461.    if (*gggcmd) {                                                               
  4462.                                                                                 
  4463.      command_processed_ok = TRUE;                                               
  4464.      memset(command,' ',COMMANDSIZE);                                           
  4465.      command_index = 0;                                                         
  4466.      for (cp = gggcmd; *cp && !isspace(*cp); cp++) {                            
  4467.        if (cp >= gggcmd+COMMANDSIZE) {                                          
  4468.        ERR1("Invalid command.  Try \"MENU bookmarkname\" or \"QUIT\"");         
  4469.          command_processed_ok = FALSE;                                          
  4470.        }                                                                        
  4471.        command[command_index++] = toupper(*cp);                                 
  4472.      }                                                                          
  4473.      while (*cp && isspace(*cp)) cp++;                                          
  4474.                                                                                 
  4475.      if      (!memcmp(command,"QUIT    ",8)) gp->quit = TRUE;                   
  4476.      else if (!memcmp(command,"MENU    ",8)) GGMmenu(gp,cp);                    
  4477.      else if (!memcmp(command,"OPT     ",8)                                     
  4478.            || !memcmp(command,"OPTION  ",8)                                     
  4479.            || !memcmp(command,"OPTIONS ",8)) GGMdsopt(gp,cp);                   
  4480.      else if (!memcmp(command,"TEST    ",8)) {                                  
  4481.                                               gp->test_mode = TRUE;             
  4482.                                               __ctest(NULL);                    
  4483.                                              }                                  
  4484.      else {                                                                     
  4485.        ERR1(                                                                    
  4486.  "Unknown command.  Try \"OPTIONS\", \"MENU bookmarkname\", \"QUIT\""           
  4487.            );                                                                   
  4488.        command_processed_ok = FALSE;                                            
  4489.      }                                                                          
  4490.                                                                                 
  4491.      if (command_processed_ok) strcpy(gggcmd,"");                               
  4492.                                                                                 
  4493.    }                                                                            
  4494.                                                                                 
  4495.    if (gp->quit) break;                                                         
  4496.                                                                                 
  4497.    if (last_item_selected >= 0 && gp->autoscroll) {                             
  4498.      topitem = last_item_selected;                                              
  4499.    }                                                                            
  4500.                                                                                 
  4501.    /* Process scroll request if any. */                                         
  4502.                                                                                 
  4503.    is_max = EQUAL(zscrolla,"MAX");                                              
  4504.    is_csr = zscrolla[0] == 'C';                                                 
  4505.    if      (EQUAL(zverb,"DOWN")) {                                              
  4506.      if (is_max) topitem = entrycount - ggglvl;                                 
  4507.      else        topitem += zscrolln;                                           
  4508.    }                                                                            
  4509.    else if (EQUAL(zverb,"UP")) {                                                
  4510.      if (is_max) topitem = 0;                                                   
  4511.      else        topitem -= zscrolln;                                           
  4512.    }                                                                            
  4513.    else if (EQUAL(zverb,"LEFT")) {                                              
  4514.      if (is_max) leftcol = 0;                                                   
  4515.      else        leftcol -= zscrolln;                                           
  4516.    }                                                                            
  4517.    else if (EQUAL(zverb,"RIGHT")) {                                             
  4518.      if (is_csr) zscrolln -= 13;                                                
  4519.      if (is_max) leftcol = maxcol - 67;                                         
  4520.      else        leftcol += zscrolln;                                           
  4521.    }                                                                            
  4522.    else if (EQUAL(zverb,"RETURN")) {                                            
  4523.      gp->quit = TRUE;                                                           
  4524.      break;                                                                     
  4525.    }                                                                            
  4526.    if (topitem < 0)          topitem = 0;                                       
  4527.    if (topitem > entrycount) topitem = entrycount;                              
  4528.    if (leftcol < 0)          leftcol = 0;                                       
  4529.    if (leftcol > maxcol)     leftcol = maxcol;                                  
  4530.                                                                                 
  4531.  } while (prc == 0);                                                            
  4532.                                                                                 
  4533.  return;                                                                        
  4534.                                                                                 
  4535. }                                                                               
  4536.                                                                                 
  4537. /****** Gopher a directory. ******************************************/         
  4538.                                                                                 
  4539. Bool                                                                            
  4540. GGMdir(gp,ip,as_file)                                                           
  4541. Rstruc ggcb        *gp;                                                         
  4542. Rstruc gopherinfo  *ip;                                                         
  4543. Fool                as_file;                                                    
  4544. {                                                                               
  4545.  int                entrycount;                                                 
  4546.  int                i;                                                          
  4547.  int                copysize;                                                   
  4548.  char               typechar;                                                   
  4549.  char               savechar;                                                   
  4550.  char              *p;                                                          
  4551.  char              *q;                                                          
  4552.  char              *r;                                                          
  4553.  struct textline   *tp;                                                         
  4554.  struct gopherinfo *infoarray;                                                  
  4555.  struct gopherinfo *iap;                                                        
  4556.  char               temp[16];                                                   
  4557.                                                                                 
  4558.  if (as_file) {                                                                 
  4559.    GGMvtx(gp,ip,as_file);  /* if as a file, display text as is */               
  4560.    return TRUE;                                                                 
  4561.  }                                                                              
  4562.                                                                                 
  4563.  /* The text chain contains the data from the server, which should be           
  4564.   * in the following format:                                                    
  4565.   *                                                                             
  4566.   * nDescription^Path^foo^bar                                                   
  4567.   *                                                                             
  4568.   * where the "n" in the beginning is a digit and ^ means a tab char.           
  4569.   *                                                                             
  4570.   * Logic:                                                                      
  4571.   *                                                                             
  4572.   * Build an array of gopherinfo structs from the text records.                 
  4573.   *                                                                             
  4574.   * Display them as an ISPF dynamic area pseudotable.                           
  4575.   *                                                                             
  4576.   * Let the user select them, and run GGMgofor on each one                      
  4577.   * with a struct gopherinfo built from the contents.                           
  4578.   *                                                                             
  4579.   */                                                                            
  4580.                                                                                 
  4581.  /* Determine size of array of gopherinfo structs.  This is equal to            
  4582.   * the number of text records with a valid code in the first byte.             
  4583.   */                                                                            
  4584.                                                                                 
  4585.  entrycount = 0;                                                                
  4586.  for (tp = ip->thdr.first_text_line; tp; tp = tp->next) {                       
  4587.    if (valid_code(tp->text[0])) entrycount++;                                   
  4588.  }                                                                              
  4589.                                                                                 
  4590.  if (entrycount == 0) {                                                         
  4591.    ERR1("There seems to be no information in this directory.\n");               
  4592.    return FALSE;                                                                
  4593.  }                                                                              
  4594.                                                                                 
  4595.  /* Allocate an array of structs to hold the stuff. */                          
  4596.                                                                                 
  4597.  GETMAIN(infoarray, struct gopherinfo, entrycount,"gopherinfo array");          
  4598.                                                                                 
  4599.  if (!infoarray) {                                                              
  4600.    ERR2("Not enough memory for %d gopher directory entries\n",                  
  4601.         entrycount);                                                            
  4602.    return FALSE;                                                                
  4603.  }                                                                              
  4604.                                                                                 
  4605.  /* Build the array entries. */                                                 
  4606.                                                                                 
  4607.  iap = infoarray;                                                               
  4608.  for (tp = ip->thdr.first_text_line; tp; tp = tp->next) {                       
  4609.    typechar = tp->text[0];                                                      
  4610.    if (valid_code(typechar)) {                                                  
  4611.      r = &tp->text[tp->text_length];                                            
  4612.      savechar = *r;                                                             
  4613.      *r = '\t';                                                                 
  4614.      memset(iap,0,sizeof(struct gopherinfo));                                   
  4615.      iap->port = GOPHER_PORT_NUMBER;                                            
  4616.      iap->type = (gophertype)typechar;                                          
  4617.      p = &tp->text[1];                                                          
  4618.      q = strchr(p,'\t');                                                        
  4619.      copysize = sizeof(iap->desc)-1;                                            
  4620.      if (copysize > q-p) copysize = q-p;                                        
  4621.      memcpy(iap->desc,p,copysize);                                              
  4622.      if (q < r) {                                                               
  4623.        p = q+1;                                                                 
  4624.        q = strchr(p,'\t');                                                      
  4625.        copysize = sizeof(iap->path)-1;                                          
  4626.        if (copysize > q-p) copysize = q-p;                                      
  4627.        memcpy(iap->path,p,copysize);                                            
  4628.        if (q < r) {                                                             
  4629.          p = q+1;                                                               
  4630.          q = strchr(p,'\t');                                                    
  4631.          copysize = sizeof(iap->host)-1;                                        
  4632.          if (copysize > q-p) copysize = q-p;                                    
  4633.          memcpy(iap->host,p,copysize);                                          
  4634.          if (q < r) {                                                           
  4635.            p = q+1;                                                             
  4636.            q = strchr(p,'\t');                                                  
  4637.            memset(temp,0,sizeof(temp));                                         
  4638.            copysize = sizeof(temp)-1;                                           
  4639.            if (copysize > q-p) copysize = q-p;                                  
  4640.            memcpy(temp,p,copysize);                                             
  4641.            iap->port = atoi(temp);                                              
  4642.          }                                                                      
  4643.        }                                                                        
  4644.      }                                                                          
  4645.                                                                                 
  4646.      strcpy(iap->bmds,gp->current_bookmark_ds);                                 
  4647.                                                                                 
  4648.      *r = savechar;                                                             
  4649.      iap++;                                                                     
  4650.    }                                                                            
  4651.  }                                                                              
  4652.                                                                                 
  4653.  if (gp->debug_mode) {                                                          
  4654.    for (iap = infoarray, i = entrycount; i > 0; iap++, i--) {                   
  4655.      fprintf(gp->debug_file,"GGMdir: type = %d\n",iap->type);                   
  4656.      fprintf(gp->debug_file,"GGMdir: port = %d\n",iap->port);                   
  4657.      fprintf(gp->debug_file,"GGMdir: path = %s\n",iap->path);                   
  4658.      fprintf(gp->debug_file,"GGMdir: host = %s\n",iap->host);                   
  4659.      fprintf(gp->debug_file,"GGMdir: desc = %s\n",iap->desc);                   
  4660.      fprintf(gp->debug_file,"GGMdir: bmds = %s\n",iap->bmds);                   
  4661.      fprintf(gp->debug_file,"\n");                                              
  4662.    }                                                                            
  4663.  }                                                                              
  4664.                                                                                 
  4665.  display_dynamic_area(gp,ip,infoarray,entrycount);                              
  4666.                                                                                 
  4667.  FREEMAIN(infoarray,"gopherinfo array");                                        
  4668.                                                                                 
  4669.  return TRUE;                                                                   
  4670. }                                                                               
  4671.                                                                                 
  4672. ./   ADD NAME=GGMDISC                                                           
  4673.                                                                                 
  4674.  /********************************************************************/         
  4675.  /*                                                                  */         
  4676.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4677.  /*                                                                  */         
  4678.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4679.  /*                                                                  */         
  4680.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4681.  /* including the implied warranties of merchantability and fitness, */         
  4682.  /* are expressly denied.                                            */         
  4683.  /*                                                                  */         
  4684.  /* Provided this copyright notice is included, this software may    */         
  4685.  /* be freely distributed and not offered for sale.                  */         
  4686.  /*                                                                  */         
  4687.  /* Changes or modifications may be made and used only by the maker  */         
  4688.  /* of same, and not further distributed.  Such modifications should */         
  4689.  /* be mailed to the author for consideration for addition to the    */         
  4690.  /* software and incorporation in subsequent releases.               */         
  4691.  /*                                                                  */         
  4692.  /********************************************************************/         
  4693.                                                                                 
  4694. #pragma  csect(code,  "GG@DISC ")                                               
  4695. #pragma  csect(static,"GG$DISC ")                                               
  4696. #include "gg.h"                                                                 
  4697.                                                                                 
  4698. /****** Disconnect from gopher server. ********************************/        
  4699.                                                                                 
  4700. void                                                                            
  4701. GGMdisc(gp,sp)                                                                  
  4702. Rstruc ggcb        *gp;                                                         
  4703. Rstruc connection  *sp;                                                         
  4704. {                                                                               
  4705.  int                closerc;                                                    
  4706.  struct recvstruct *R;                                                          
  4707.                                                                                 
  4708.  /* If local mode, close temporary file and return. */                          
  4709.                                                                                 
  4710.  if ((R=gp->recvp)) {                                                           
  4711.    if (R->outfp) {                                                              
  4712.      if (fclose(R->outfp) < 0) {                                                
  4713.        CRIT1("Error closing local mode temporary file");                        
  4714.      }                                                                          
  4715.      R->outfp = NULL;                                                           
  4716.    }                                                                            
  4717.                                                                                 
  4718.    sp->connected_to_server   = FALSE;                                           
  4719.                                                                                 
  4720.    FREEMAIN(gp->recvp,"local mode recv struct");                                
  4721.    gp->recvp = NULL;                                                            
  4722.    return;                                                                      
  4723.  }                                                                              
  4724.                                                                                 
  4725.  sp->reconnect_in_progress = FALSE;                                             
  4726.  sp->closing_connection    = TRUE;                                              
  4727.                                                                                 
  4728.  if (sp->connection_broken) {                                                   
  4729.    if (gp->debug_file) {                                                        
  4730.      fprintf(gp->debug_file,                                                    
  4731.   "Client %s (%s) connection with gopher server on %s (%s) was lost\n",         
  4732.           gp->client_hostname,                                                  
  4733.           gp->client_ip_addrstr,                                                
  4734.           gp->server_hostname,                                                  
  4735.           gp->server_ip_addrstr);                                               
  4736.    }                                                                            
  4737.    sp->connected_to_server   = FALSE;                                           
  4738.  }                                                                              
  4739.  else {                                                                         
  4740.                                                                                 
  4741.    /* In case of some kind of protocol error, don't let things hang. */         
  4742.                                                                                 
  4743.    GGMesrvr(gp,sp);         /* End server read */                               
  4744.                                                                                 
  4745.    if (gp->debug_file) {                                                        
  4746.      fprintf(gp->debug_file,                                                    
  4747.       "Client %s (%s) disconnecting from gopher server on %s (%s)\n",           
  4748.           gp->client_hostname,                                                  
  4749.           gp->client_ip_addrstr,                                                
  4750.           gp->server_hostname,                                                  
  4751.           gp->server_ip_addrstr);                                               
  4752.    }                                                                            
  4753.                                                                                 
  4754.    (void)GGMivput(gp,"GGSOLDER ",gp->server_hostname,-1);                       
  4755.    (void)GGMivput(gp,"GGSOLDIP ",gp->server_ip_addrstr,-1);                     
  4756.    (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                    
  4757.    (void)GGMispf(gp,"DISPLAY PANEL(GGMLDISC)");                                 
  4758.                                                                                 
  4759.    /* In case of some kind of protocol error, don't let things hang. */         
  4760.                                                                                 
  4761.    GGMesrvr(gp,sp);                   /* End server read */                     
  4762.                                                                                 
  4763.    sp->connected_to_server   = FALSE;                                           
  4764.                                                                                 
  4765.    TCP_DEBUG_ON;                                                                
  4766.    closerc = close(sp->ns);                                                     
  4767.    TCP_DEBUG_OFF;                                                               
  4768.                                                                                 
  4769.    if (closerc < 0) {                                                           
  4770.      ERR2("TCP/IP error: close() failed to disconnect from server %s.",         
  4771.           gp->ggserver);                                                        
  4772.    }                                                                            
  4773.  }                                                                              
  4774.                                                                                 
  4775.  return;                                                                        
  4776. }                                                                               
  4777.                                                                                 
  4778. ./   ADD NAME=GGMDISPL                                                          
  4779.                                                                                 
  4780.  /********************************************************************/         
  4781.  /*                                                                  */         
  4782.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4783.  /*                                                                  */         
  4784.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4785.  /*                                                                  */         
  4786.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4787.  /* including the implied warranties of merchantability and fitness, */         
  4788.  /* are expressly denied.                                            */         
  4789.  /*                                                                  */         
  4790.  /* Provided this copyright notice is included, this software may    */         
  4791.  /* be freely distributed and not offered for sale.                  */         
  4792.  /*                                                                  */         
  4793.  /* Changes or modifications may be made and used only by the maker  */         
  4794.  /* of same, and not further distributed.  Such modifications should */         
  4795.  /* be mailed to the author for consideration for addition to the    */         
  4796.  /* software and incorporation in subsequent releases.               */         
  4797.  /*                                                                  */         
  4798.  /********************************************************************/         
  4799.                                                                                 
  4800.  /********************************************************************/         
  4801.                                                                                 
  4802. #pragma  csect(code,  "GG@DISPL")                                               
  4803. #pragma  csect(static,"GG$DISPL")                                               
  4804. #include "gg.h"                                                                 
  4805.                                                                                 
  4806. #ifdef FETCH                                                                    
  4807. #define VL_BIT(X) ((unsigned int)(X) | 0x80000000)                              
  4808. #else                                                                           
  4809. #define VL_BIT(X) (X)                                                           
  4810. #endif                                                                          
  4811.                                                                                 
  4812. /****** Display ISPF panel. ******************************************/         
  4813.                                                                                 
  4814. int                                                                             
  4815. GGMdispl(gp,pan8)                                                               
  4816. Rstruc ggcb    *gp;                                                             
  4817. char           *pan8;                                                           
  4818. {                                                                               
  4819.                                                                                 
  4820.  if (gp->setmsg) {                                                              
  4821.    gp->ispfrc = ISPLINK("DISPLAY ", pan8, VL_BIT("ISRZ002 "));                  
  4822.  }                                                                              
  4823.  else {                                                                         
  4824.    gp->ispfrc = ISPLINK("DISPLAY ", VL_BIT(pan8));                              
  4825.  }                                                                              
  4826.                                                                                 
  4827.  if (gp->ispfrc > 8) GGMierr(gp);   /* display ISPF error */                    
  4828.                                                                                 
  4829.  gp->setmsg = FALSE;                                                            
  4830.                                                                                 
  4831.  return gp->ispfrc;                                                             
  4832. }                                                                               
  4833.                                                                                 
  4834. ./   ADD NAME=GGMDSOPT,SSI=01000057                                             
  4835.                                                                                 
  4836.  /********************************************************************/         
  4837.  /*                                                                  */         
  4838.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4839.  /*                                                                  */         
  4840.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4841.  /*                                                                  */         
  4842.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4843.  /* including the implied warranties of merchantability and fitness, */         
  4844.  /* are expressly denied.                                            */         
  4845.  /*                                                                  */         
  4846.  /* Provided this copyright notice is included, this software may    */         
  4847.  /* be freely distributed and not offered for sale.                  */         
  4848.  /*                                                                  */         
  4849.  /* Changes or modifications may be made and used only by the maker  */         
  4850.  /* of same, and not further distributed.  Such modifications should */         
  4851.  /* be mailed to the author for consideration for addition to the    */         
  4852.  /* software and incorporation in subsequent releases.               */         
  4853.  /*                                                                  */         
  4854.  /********************************************************************/         
  4855.                                                                                 
  4856. #pragma  csect(code,  "GG@DSOPT")                                               
  4857. #pragma  csect(static,"GG$DSOPT")                                               
  4858. #include "gg.h"                                                                 
  4859.                                                                                 
  4860. /****** Set options. *************************************************/         
  4861.                                                                                 
  4862. static void                                                                     
  4863. set_options(gp,panelname,which)                                                 
  4864. Rstruc ggcb       *gp;                                                          
  4865. char              *panelname;                                                   
  4866. enum user_option   which;                                                       
  4867. {                                                                               
  4868.                                                                                 
  4869.  while (GGMdispl(gp,panelname) == 0) {                                          
  4870.    GGMsopt(gp,which);               /* Actually set options */                  
  4871.  }                                                                              
  4872.                                                                                 
  4873.  return;                                                                        
  4874. }                                                                               
  4875.                                                                                 
  4876. /****** Option ... set GOPHER default processing options. ***********/          
  4877.                                                                                 
  4878. void                                                                            
  4879. GGMdsopt(gp,option)                                                             
  4880. Rstruc ggcb *gp;                                                                
  4881. char        *option;                                                            
  4882. {                                                                               
  4883.  Bool        asked_for;                                                         
  4884.  Bool        force_choice;                                                      
  4885.  char        ggchoice[9];                                                       
  4886.                                                                                 
  4887.  force_choice = FALSE;                                                          
  4888.                                                                                 
  4889.  do {                                                                           
  4890.                                                                                 
  4891.    asked_for = TRUE;                                                            
  4892.                                                                                 
  4893.    if (!force_choice && option && *option) {                                    
  4894.      strncpy(ggchoice,option,sizeof(ggchoice)-1);                               
  4895.                                                                                 
  4896.    }                                                                            
  4897.    else {                                                                       
  4898.                                                                                 
  4899.      (void)GGMispf(gp,"ADDPOP");                                                
  4900.      if (GGMdispl(gp,"GGMPOPT ") > 0) {                                         
  4901.        asked_for = FALSE;                                                       
  4902.      }                                                                          
  4903.      else {                                                                     
  4904.        (void)GGMivget(gp,"GGCHOICE ",ggchoice,sizeof(ggchoice));                
  4905.        if (*ggchoice == '?') {                                                  
  4906.          ERR1("Invalid choice;\                                                 
  4907. Move the cursor to a selection (or type S next to it) and press ENTER."         
  4908.              );                                                                 
  4909.        }                                                                        
  4910.      }                                                                          
  4911.                                                                                 
  4912.      (void)GGMispf(gp,"REMPOP");                                                
  4913.    }                                                                            
  4914.                                                                                 
  4915.    if (asked_for) {                                                             
  4916.                                                                                 
  4917.      if      (EQUAL(ggchoice,"1")) {                                            
  4918.        set_options(gp,"GGMOPT1 ",OPTION_VIEW);                                  
  4919.        break;                                                                   
  4920.      }                                                                          
  4921.      else if (EQUAL(ggchoice,"2")) {                                            
  4922.        set_options(gp,"GGMOPT2 ",OPTION_OTHER);                                 
  4923.        break;                                                                   
  4924.      }                                                                          
  4925.      else {                                                                     
  4926.        ERR1("Invalid choice;\                                                   
  4927. Move the cursor to a selection (or type S next to it) and press ENTER."         
  4928.            );                                                                   
  4929.        force_choice = TRUE;                                                     
  4930.        continue;                                                                
  4931.      }                                                                          
  4932.    }                                                                            
  4933.                                                                                 
  4934.  } while (asked_for);                                                           
  4935.                                                                                 
  4936.  return;                                                                        
  4937.                                                                                 
  4938. }                                                                               
  4939.                                                                                 
  4940. ./   ADD NAME=GGMDUMP                                                           
  4941.                                                                                 
  4942.  /********************************************************************/         
  4943.  /*                                                                  */         
  4944.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  4945.  /*                                                                  */         
  4946.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  4947.  /*                                                                  */         
  4948.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  4949.  /* including the implied warranties of merchantability and fitness, */         
  4950.  /* are expressly denied.                                            */         
  4951.  /*                                                                  */         
  4952.  /* Provided this copyright notice is included, this software may    */         
  4953.  /* be freely distributed and not offered for sale.                  */         
  4954.  /*                                                                  */         
  4955.  /* Changes or modifications may be made and used only by the maker  */         
  4956.  /* of same, and not further distributed.  Such modifications should */         
  4957.  /* be mailed to the author for consideration for addition to the    */         
  4958.  /* software and incorporation in subsequent releases.               */         
  4959.  /*                                                                  */         
  4960.  /********************************************************************/         
  4961.                                                                                 
  4962. #pragma  csect(code,  "GG@DUMP ")                                               
  4963. #pragma  csect(static,"GG$DUMP ")                                               
  4964. #include "gg.h"                                                                 
  4965.                                                                                 
  4966. /****** Dump some data. **********************************************/         
  4967.                                                                                 
  4968. void                                                                            
  4969. GGMdump(struct ggcb *gp, char *label, char *p,int r)                            
  4970. {                                                                               
  4971.  int i;                                                                         
  4972.                                                                                 
  4973.  if (!gp->debug_file) return;                                                   
  4974.                                                                                 
  4975.  if (r == -2) {                                                                 
  4976.    fprintf(gp->debug_file,"%s:  %d\n",label,(int)p);                            
  4977.    return;                                                                      
  4978.  }                                                                              
  4979.                                                                                 
  4980.  if (r == -1) r = strlen(p);                                                    
  4981.                                                                                 
  4982.  fprintf(gp->debug_file,"%s:   (%d characters)\n",label,r);                     
  4983.  for (i=0;i<77;i++) fprintf(gp->debug_file,"-");                                
  4984.  fprintf(gp->debug_file,"\n");                                                  
  4985.  for (i=0;i<r;i++) {                                                            
  4986.    char c = *(p+i);                                                             
  4987.    if (isprint(c))  fprintf(gp->debug_file,"%c",c);                             
  4988.    else             fprintf(gp->debug_file,"<0x%2.2x>",c);                      
  4989.  }                                                                              
  4990.  fprintf(gp->debug_file,"\n");                                                  
  4991.  for (i=0;i<77;i++) fprintf(gp->debug_file,"-");                                
  4992.  fprintf(gp->debug_file,"\n");                                                  
  4993.                                                                                 
  4994.  return;                                                                        
  4995.                                                                                 
  4996. }                                                                               
  4997.                                                                                 
  4998. ./   ADD NAME=GGMESRVR                                                          
  4999.                                                                                 
  5000.  /********************************************************************/         
  5001.  /*                                                                  */         
  5002.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5003.  /*                                                                  */         
  5004.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5005.  /*                                                                  */         
  5006.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5007.  /* including the implied warranties of merchantability and fitness, */         
  5008.  /* are expressly denied.                                            */         
  5009.  /*                                                                  */         
  5010.  /* Provided this copyright notice is included, this software may    */         
  5011.  /* be freely distributed and not offered for sale.                  */         
  5012.  /*                                                                  */         
  5013.  /* Changes or modifications may be made and used only by the maker  */         
  5014.  /* of same, and not further distributed.  Such modifications should */         
  5015.  /* be mailed to the author for consideration for addition to the    */         
  5016.  /* software and incorporation in subsequent releases.               */         
  5017.  /*                                                                  */         
  5018.  /********************************************************************/         
  5019.                                                                                 
  5020. #pragma  csect(code,  "GG@ESRVR")                                               
  5021. #pragma  csect(static,"GG$ESRVR")                                               
  5022. #include "gg.h"                                                                 
  5023.                                                                                 
  5024. /****** End server read. *********************************************/         
  5025.                                                                                 
  5026. void                                                                            
  5027. GGMesrvr(gp,sp)                                                                 
  5028. Rstruc ggcb       *gp;                                                          
  5029. Rstruc connection *sp;                                                          
  5030. {                                                                               
  5031.  char             *lp;                                                          
  5032.  Bool              found_more_server_data = FALSE;                              
  5033.                                                                                 
  5034.  GGMclrtx(gp,NULL);                    /* Clear text */                         
  5035.                                                                                 
  5036.  if (gp->recvp) return;                /* Skip if non-socket */                 
  5037.                                                                                 
  5038.  do {                                                                           
  5039.                                                                                 
  5040.    if (GGMgsrvl(gp,sp,&lp,FALSE)) {    /* Get server line */                    
  5041.      if (lp) {                                                                  
  5042.        found_more_server_data = TRUE;                                           
  5043.        (void)GGMouttx(gp,lp,NULL);     /* Output text line */                   
  5044.      }                                                                          
  5045.    }                                                                            
  5046.                                                                                 
  5047.  } while (lp);                                                                  
  5048.                                                                                 
  5049.  if (found_more_server_data) {                                                  
  5050.    ERR1(                                                                        
  5051. "More data was returned by the GOPHER server than GOPHER expected."             
  5052.        );                                                                       
  5053.    GGMvtx(gp,NULL,TRUE);              /* View text */                           
  5054.  }                                                                              
  5055.                                                                                 
  5056.  return;                                                                        
  5057. }                                                                               
  5058.                                                                                 
  5059. ./   ADD NAME=GGMFREEM                                                          
  5060.                                                                                 
  5061.  /********************************************************************/         
  5062.  /*                                                                  */         
  5063.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5064.  /*                                                                  */         
  5065.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5066.  /*                                                                  */         
  5067.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5068.  /* including the implied warranties of merchantability and fitness, */         
  5069.  /* are expressly denied.                                            */         
  5070.  /*                                                                  */         
  5071.  /* Provided this copyright notice is included, this software may    */         
  5072.  /* be freely distributed and not offered for sale.                  */         
  5073.  /*                                                                  */         
  5074.  /* Changes or modifications may be made and used only by the maker  */         
  5075.  /* of same, and not further distributed.  Such modifications should */         
  5076.  /* be mailed to the author for consideration for addition to the    */         
  5077.  /* software and incorporation in subsequent releases.               */         
  5078.  /*                                                                  */         
  5079.  /********************************************************************/         
  5080.                                                                                 
  5081. #pragma  csect(code,  "GG@FREEM")                                               
  5082. #pragma  csect(static,"GG$FREEM")                                               
  5083. #include "gg.h"                                                                 
  5084.                                                                                 
  5085. /****** Free memory. *************************************************/         
  5086.                                                                                 
  5087. void                                                                            
  5088. GGMfreem(gp,stuff,whatfor)                                                      
  5089. Rstruc ggcb    *gp;                                                             
  5090. char           *stuff;                                                          
  5091. char           *whatfor;                                                        
  5092. {                                                                               
  5093.                                                                                 
  5094.  free(stuff);                                                                   
  5095.                                                                                 
  5096.  if (gp->debug_file) {                                                          
  5097.    fprintf(gp->debug_file,"GGMfreem: freed memory for %s\n", whatfor);          
  5098.  }                                                                              
  5099.  return;                                                                        
  5100.                                                                                 
  5101. }                                                                               
  5102.                                                                                 
  5103. ./   ADD NAME=GGMGETDS,SSI=010C0029                                             
  5104.                                                                                 
  5105.  /********************************************************************/         
  5106.  /*                                                                  */         
  5107.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5108.  /*                                                                  */         
  5109.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5110.  /*                                                                  */         
  5111.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5112.  /* including the implied warranties of merchantability and fitness, */         
  5113.  /* are expressly denied.                                            */         
  5114.  /*                                                                  */         
  5115.  /* Provided this copyright notice is included, this software may    */         
  5116.  /* be freely distributed and not offered for sale.                  */         
  5117.  /*                                                                  */         
  5118.  /* Changes or modifications may be made and used only by the maker  */         
  5119.  /* of same, and not further distributed.  Such modifications should */         
  5120.  /* be mailed to the author for consideration for addition to the    */         
  5121.  /* software and incorporation in subsequent releases.               */         
  5122.  /*                                                                  */         
  5123.  /********************************************************************/         
  5124.                                                                                 
  5125. #pragma  csect(code,  "GG@GETDS")                                               
  5126. #pragma  csect(static,"GG$GETDS")                                               
  5127. #include "gg.h"                                                                 
  5128.                                                                                 
  5129. #define DUMMY_FILE_POINTER_FOR_PDS  (FILE *)(-1)                                
  5130.                                                                                 
  5131. struct sysout    {                                                              
  5132.                   int        copies;                                            
  5133.                   char       class [2];                                         
  5134.                   char       dest  [9];                                         
  5135.                   char       forms [5];                                         
  5136.                   char       ucs   [5];                                         
  5137.                  };                                                             
  5138.                                                                                 
  5139. #define FULLSYSOUT                                                              
  5140.                                                                                 
  5141. /****** Function to close sequential data set after extraction. ******/         
  5142.                                                                                 
  5143. static void                                                                     
  5144. close_seq(gp,ep,xfp,final)                                                      
  5145. Rstruc ggcb         *gp;                                                        
  5146. Rstruc extraction   *ep;                                                        
  5147. FILE                *xfp;                                                       
  5148. Fool                 final;                                                     
  5149. {                                                                               
  5150.                                                                                 
  5151.  if (fclose(xfp) < 0) {                                                         
  5152.    /* perror(ep->dsname); */                                                    
  5153.    ERR2("An error occurred closing %s.", ep->dsname);                           
  5154.    gp->extract_close_error = TRUE;                                              
  5155.  }                                                                              
  5156.                                                                                 
  5157. }                                                                               
  5158.                                                                                 
  5159. /****** Function to close partitioned data set after extraction. *****/         
  5160.                                                                                 
  5161. static void                                                                     
  5162. close_pds(gp,ep,xfp,final)                                                      
  5163. Rstruc ggcb         *gp;                                                        
  5164. Rstruc extraction   *ep;                                                        
  5165. FILE                *xfp;                                                       
  5166. Fool                 final;                                                     
  5167. {                                                                               
  5168.                                                                                 
  5169.  if (final) {                                                                   
  5170.    (void)GGMunalc(ep->ddname);     /* Unallocate the PDS */                     
  5171.  }                                                                              
  5172.  else {                                                                         
  5173.    if (fclose(xfp) < 0) {                                                       
  5174.      /* perror(ep->dsname); */                                                  
  5175.      ERR2("An error occurred closing %s.", ep->dsname);                         
  5176.      gp->extract_close_error = TRUE;                                            
  5177.    }                                                                            
  5178.  }                                                                              
  5179.                                                                                 
  5180. }                                                                               
  5181.                                                                                 
  5182. /****** Function to close SYSOUT print file after printing. **********/         
  5183.                                                                                 
  5184. static void                                                                     
  5185. close_jes(gp,ep,xfp,final)                                                      
  5186. Rstruc ggcb         *gp;                                                        
  5187. Rstruc extraction   *ep;                                                        
  5188. FILE                *xfp;                                                       
  5189. Fool                 final;                                                     
  5190. {                                                                               
  5191.                                                                                 
  5192.  if (fclose(xfp) < 0) {                                                         
  5193.    /* perror(ep->dsname); */                                                    
  5194.    ERR2("An error occurred closing %s.", ep->dsname);                           
  5195.    gp->extract_close_error = TRUE;                                              
  5196.  }                                                                              
  5197.  if (final) {                                                                   
  5198.    (void)GGMunalc(ep->ddname);     /* Unallocate the SYSOUT file */             
  5199.  }                                                                              
  5200.                                                                                 
  5201. }                                                                               
  5202.                                                                                 
  5203. /****** Allocate SYSOUT file. ****************************************/         
  5204.                                                                                 
  5205. static Bool                                                                     
  5206. allocate_sysout(ep,sp)                                                          
  5207. Rstruc extraction   *ep;                                                        
  5208. Rstruc sysout       *sp;                                                        
  5209. {                                                                               
  5210.  int          i;                                                                
  5211.  int          rc;                                                               
  5212.  char        *cp;                                                               
  5213.  __S99parms   stuff99;   /* The manual has it wrong.  No "struct". */           
  5214.  TEXTUNIT    *tu [ 7];                                                          
  5215.  TEXTUNIT     tu_sysout;                                                        
  5216.  TEXTUNIT     tu_copies;                                                        
  5217.  TEXTUNIT     tu_dest;                                                          
  5218.  TEXTUNIT     tu_forms;                                                         
  5219.  TEXTUNIT     tu_ucs;                                                           
  5220.  TEXTUNIT     tu_rtddn;                                                         
  5221.                                                                                 
  5222.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  5223.                                                                                 
  5224.  stuff99.__S99RBLN   = 20;                                                      
  5225.  stuff99.__S99VERB   = S99VRBAL;                                                
  5226.  stuff99.__S99FLAG1  = S99NOCNV << 8;                                           
  5227.  stuff99.__S99ERROR  = 0;                                                       
  5228.  stuff99.__S99INFO   = 0;                                                       
  5229.  stuff99.__S99TXTPP  = tu;                                                      
  5230.  stuff99.__S99FLAG2  = 0;                                                       
  5231.                                                                                 
  5232.  i = 0;                                                                         
  5233.                                                                                 
  5234.  tu[i++] = &tu_sysout;                                                          
  5235.                                                                                 
  5236.  tu_sysout.key        = DALSYSOU;                                               
  5237.  tu_sysout.num        = 1;                                                      
  5238.  tu_sysout.ent.len    = 1;                                                      
  5239.  tu_sysout.ent.prm[0] = toupper(sp->class[0]);                                  
  5240.                                                                                 
  5241.  tu[i++] = &tu_copies;                                                          
  5242.                                                                                 
  5243.  tu_copies.key        = DALCOPYS;                                               
  5244.  tu_copies.num        = 1;                                                      
  5245.  tu_copies.ent.len    = 1;                                                      
  5246.  tu_copies.ent.prm[0] = (unsigned char)sp->copies;                              
  5247.                                                                                 
  5248.  if (sp->dest[0] > ' ') {                                                       
  5249.                                                                                 
  5250.   tu[i++] = &tu_dest;                                                           
  5251.                                                                                 
  5252.   tu_dest.key          = DALSUSER;                                              
  5253.   tu_dest.num          = 1;                                                     
  5254.   copy_uppercase_and_strip_trailing(tu_dest.ent.prm,sp->dest,cp);               
  5255.   tu_dest.ent.len      = cp - tu_dest.ent.prm;                                  
  5256.                                                                                 
  5257.  }                                                                              
  5258.                                                                                 
  5259.  if (sp->forms[0] > ' ') {                                                      
  5260.                                                                                 
  5261.   tu[i++] = &tu_forms;                                                          
  5262.                                                                                 
  5263.   tu_forms.key         = DALSFMNO;                                              
  5264.   tu_forms.num         = 1;                                                     
  5265.   copy_uppercase_and_strip_trailing(tu_forms.ent.prm,sp->forms,cp);             
  5266.   tu_forms.ent.len     = cp - tu_forms.ent.prm;                                 
  5267.                                                                                 
  5268.  }                                                                              
  5269.                                                                                 
  5270.  if (sp->ucs[0] > ' ') {                                                        
  5271.                                                                                 
  5272.   tu[i++] = &tu_ucs;                                                            
  5273.                                                                                 
  5274.   tu_ucs.key           = DALUCS;                                                
  5275.   tu_ucs.num           = 1;                                                     
  5276.   copy_uppercase_and_strip_trailing(tu_ucs.ent.prm,sp->ucs,cp);                 
  5277.   tu_ucs.ent.len       = cp - tu_ucs.ent.prm;                                   
  5278.                                                                                 
  5279.  }                                                                              
  5280.                                                                                 
  5281.  tu[i++] = &tu_rtddn;                                                           
  5282.                                                                                 
  5283.  tu_rtddn.key         = DALRTDDN;                                               
  5284.  tu_rtddn.num         = 1;                                                      
  5285.  tu_rtddn.ent.len     = 8;                                                      
  5286.  memset(tu_rtddn.ent.prm,' ',8);                                                
  5287.                                                                                 
  5288.  tu[i] = (void *)0x80000000;                                                    
  5289.                                                                                 
  5290.  rc = svc99(&stuff99);                                                          
  5291.                                                                                 
  5292.  if (rc == 0) {                                                                 
  5293.    memcpy(ep->ddname,(char *)tu_rtddn.ent.prm,8);                               
  5294.    ep->ddname[8] = ' ';                                                         
  5295.    *(strchr(ep->ddname,' ')) = '\0';                                            
  5296.    return TRUE;                                                                 
  5297.  }                                                                              
  5298.  else {                                                                         
  5299.    GGMdfail(rc,&stuff99);                                                       
  5300.    return FALSE;                                                                
  5301.  }                                                                              
  5302. }                                                                               
  5303.                                                                                 
  5304. /****** Prompt user for the name of a data set to extract into. ******/         
  5305.                                                                                 
  5306. FILE *                                                                          
  5307. GGMgetds(gp,ep)                                                                 
  5308. Rstruc ggcb         *gp;                                                        
  5309. Rstruc extraction   *ep;                                                        
  5310. {                                                                               
  5311.  FILE               *xfp;                                                       
  5312.  char               *bufptr;                                                    
  5313.  Bool                asked_for;                                                 
  5314.  Bool                do_warn;                                                   
  5315.  Bool                is_not_gopher_menu;                                        
  5316.  struct sysout       sys;                                                       
  5317.  char                ggexdsn[65];    /* data set name for extraction */         
  5318.  char                ggbmdsn[65];    /* data set name for bookmark   */         
  5319.  char                ggexapp [4];    /* YES or NO for append mode    */         
  5320.  char                ggextab [4];    /* YES or NO for tab expansion  */         
  5321.  char                ggexblk [4];    /* YES or NO for blank after sep*/         
  5322.  char                ggexsep[81];    /* Separator line (optional)    */         
  5323.  char                ggexpmp [9];    /* PDS member name prefix       */         
  5324.  char                ggexscl [2];    /* Print SYSOUT class name      */         
  5325.  char                ggexsco [4];    /* Print SYSOUT copies number   */         
  5326.  char                ggexsde [9];    /* Print SYSOUT destination     */         
  5327.  char                ggexsfo [5];    /* Print SYSOUT forms           */         
  5328.  char                ggexsuc [5];    /* Print SYSOUT UCS             */         
  5329.  char                ddname  [9];                                               
  5330.  char                member  [9];                                               
  5331.  char                pdspec [32];                                               
  5332.  char                quoted_dsname [67];                                        
  5333.  char                formatted_number [11];                                     
  5334.  char                buffer [RBUFSIZE];                                         
  5335.                                                                                 
  5336.                                                                                 
  5337.  /* Display panel asking for data set name into which to extract. */            
  5338.                                                                                 
  5339.  xfp = NULL;                                                                    
  5340.  asked_for = TRUE;                                                              
  5341.                                                                                 
  5342.  (void)GGMispf(gp,"ADDPOP");                                                    
  5343.                                                                                 
  5344.  (void)GGMivput(gp,"GGALLPR ",                                                  
  5345. #ifdef FULLSYSOUT                                                               
  5346.                      "Y",                                                       
  5347. #else                                                                           
  5348.                      "",                                                        
  5349. #endif                                                                          
  5350.                      -1);                                                       
  5351.                                                                                 
  5352.  while (xfp == NULL) {                                                          
  5353.                                                                                 
  5354.    /* Keep asking for a dsname until one works or END pressed. */               
  5355.                                                                                 
  5356.    if (GGMdispl(gp,ep->panelname) > 0) {                                        
  5357.      WARN1("Request cancelled, because you pressed END.");                      
  5358.      asked_for = FALSE;                                                         
  5359.      xfp = NULL;                                                                
  5360.      break;                                                                     
  5361.    }                                                                            
  5362.                                                                                 
  5363.    switch (ep->ex) {                                                            
  5364.      case EXTRACT_IT:                                                           
  5365.           (void)GGMivget(gp,"GGEXDSN ",ggexdsn,sizeof(ggexdsn));                
  5366.           (void)GGMivget(gp,"GGEXTAB ",ggextab,sizeof(ggextab));                
  5367.           if (ep->mode == PDS) {                                                
  5368.             (void)GGMivget(gp,"GGEXPMP ",ggexpmp,sizeof(ggexpmp));              
  5369.           }                                                                     
  5370.           else {                                                                
  5371.             (void)GGMivget(gp,"GGEXAPP ",ggexapp,sizeof(ggexapp));              
  5372.             (void)GGMivget(gp,"GGEXBLK ",ggexblk,sizeof(ggexblk));              
  5373.             (void)GGMivget(gp,"GGEXSEP ",ggexsep,sizeof(ggexsep));              
  5374.           }                                                                     
  5375.           break;                                                                
  5376.      case PRINT_IT:                                                             
  5377.           (void)GGMivget(gp,"GGEXSCL ",ggexscl,sizeof(ggexscl));                
  5378.           (void)GGMivget(gp,"GGEXSCO ",ggexsco,sizeof(ggexsco));                
  5379. #ifdef FULLSYSOUT                                                               
  5380.           (void)GGMivget(gp,"GGEXSDE ",ggexsde,sizeof(ggexsde));                
  5381.           (void)GGMivget(gp,"GGEXSFO ",ggexsfo,sizeof(ggexsfo));                
  5382.           (void)GGMivget(gp,"GGEXSUC ",ggexsuc,sizeof(ggexsuc));                
  5383. #else                                                                           
  5384.           *ggexsde = '\0';                                                      
  5385.           *ggexsfo = '\0';                                                      
  5386.           *ggexsuc = '\0';                                                      
  5387. #endif                                                                          
  5388.           (void)GGMivget(gp,"GGEXBLK ",ggexblk,sizeof(ggexblk));                
  5389.           (void)GGMivget(gp,"GGEXSEP ",ggexsep,sizeof(ggexsep));                
  5390.           break;                                                                
  5391.      case BOOKMARK_IT:                                                          
  5392.           (void)GGMivget(gp,"GGBMDSN ",ggbmdsn,sizeof(ggbmdsn));                
  5393.           break;                                                                
  5394.    }                                                                            
  5395.                                                                                 
  5396.    if (ep->mode == PDS) {                                                       
  5397.                                                                                 
  5398.      ep->closer = close_pds;                                                    
  5399.      ep->appending = FALSE;                                                     
  5400.      ep->blanking  = FALSE;                                                     
  5401.      strcpy(ep->separator,"");                                                  
  5402.      strcpy(ep->ddname,"");                                                     
  5403.      strcpy(ep->member_prefix,ggexpmp);                                         
  5404.                                                                                 
  5405.      /* Note: panel forces fully-qualified name to pass to allocate */          
  5406.                                                                                 
  5407.      if (ggexdsn[0] != '\'') {                                                  
  5408.        strcpy(quoted_dsname,"'");                                               
  5409.        strcat(quoted_dsname,ggexdsn);                                           
  5410.        strcat(quoted_dsname,"'");                                               
  5411.      }                                                                          
  5412.      else strcpy(quoted_dsname,ggexdsn);                                        
  5413.                                                                                 
  5414.      /* Check if PDS already exists. */                                         
  5415.                                                                                 
  5416.      if (gp->warn_overwrite) {                                                  
  5417.        if (TEST_IF_FILE_EXISTS(xfp,quoted_dsname)) {                            
  5418.          CLEANUP_IF_FILE_EXISTS(xfp);                                           
  5419.          xfp = NULL;                                                            
  5420.          if (GGMdispl(gp,"GGMPEXPW") > 0) {                                     
  5421.            WARN1("Operation cancelled, because you pressed END.");              
  5422.            break;                                                               
  5423.          }                                                                      
  5424.        }                                                                        
  5425.      }                                                                          
  5426.                                                                                 
  5427.      if (GGMalloc(ggexdsn,ep->ddname,PDS,ep->count) != PDS) {                   
  5428.        ERR2("Allocation failed for data set %s.", ggexdsn);                     
  5429.        xfp = NULL;                                                              
  5430.        continue;                                                                
  5431.      }                                                                          
  5432.      strcpy(ep->dsname,    ggexdsn);                                            
  5433.      ep->tab_expanding = (ggextab[0] == 'Y');                                   
  5434.      do_warn = (ep->appending ? gp->warn_append : gp->warn_overwrite);          
  5435.    }                                                                            
  5436.    else if (ep->mode == JES) {                                                  
  5437.      ep->closer = close_jes;                                                    
  5438.      strcpy(ep->separator, ggexsep);                                            
  5439.      sprintf(ep->dsname,"SYSOUT class %s",ggexscl);                             
  5440.      strcpy(sys.class, ggexscl);                                                
  5441.      sys.copies = atoi(ggexsco);                                                
  5442.      if (sys.copies < 1) sys.copies = 1;                                        
  5443.      strcpy(sys.dest,  ggexsde);                                                
  5444.      strcpy(sys.forms, ggexsfo);                                                
  5445.      strcpy(sys.ucs,   ggexsuc);                                                
  5446.      ep->appending     = FALSE;                                                 
  5447.      ep->blanking      = (ggexblk[0] == 'Y');                                   
  5448.      ep->tab_expanding = TRUE;                                                  
  5449.      do_warn = FALSE;                                                           
  5450.    }                                                                            
  5451.    else if (ep->ex == BOOKMARK_IT) {                                            
  5452.      ep->closer = close_seq;                                                    
  5453.      strcpy(ep->separator, "");                                                 
  5454.      strcpy(ep->dsname,    ggbmdsn);                                            
  5455.      strcpy(ggexdsn,       ggbmdsn);                                            
  5456.      ep->appending       = TRUE;                                                
  5457.      ep->blanking        = FALSE;                                               
  5458.      ep->tab_expanding   = FALSE;                                               
  5459.      do_warn = FALSE;                                                           
  5460.    }                                                                            
  5461.    else {                                                                       
  5462.      ep->closer = close_seq;                                                    
  5463.      strcpy(ep->separator, ggexsep);                                            
  5464.      strcpy(ep->dsname,    ggexdsn);                                            
  5465.      ep->appending      = (ggexapp[0] == 'Y');                                  
  5466.      ep->blanking       = (ggexblk[0] == 'Y');                                  
  5467.      ep->tab_expanding  = (ggextab[0] == 'Y');                                  
  5468.      do_warn = (ep->appending ? gp->warn_append : gp->warn_overwrite);          
  5469.    }                                                                            
  5470.                                                                                 
  5471.    /* check if the dataset already exists */                                    
  5472.                                                                                 
  5473.    if (ep->ex == BOOKMARK_IT) {                                                 
  5474.      is_not_gopher_menu = FALSE;                                                
  5475.      if (TEST_IF_FILE_EXISTS(xfp,ggexdsn)) {                                    
  5476.        /* check that it is a gopher menu */                                     
  5477.        CLEANUP_IF_FILE_EXISTS(xfp);                                             
  5478.        xfp = fopen(ggexdsn,"r");                                                
  5479.        if (xfp) {                                                               
  5480.          *buffer = '\0';                                                        
  5481.          fgets(buffer,sizeof(buffer),xfp);                                      
  5482.          if (*buffer) {                                                         
  5483.            if ((bufptr=strchr(buffer,'\n'))) *bufptr = '\0';                    
  5484.            uppercase_in_place(buffer);                                          
  5485.            bufptr = skip_whitespace(buffer);                                    
  5486.            if (!EQUAL(bufptr,MENUIDENT)) is_not_gopher_menu = TRUE;             
  5487.          }                                                                      
  5488.          (void)fclose(xfp);                                                     
  5489.          xfp = NULL;                                                            
  5490.        }                                                                        
  5491.        if (is_not_gopher_menu) {                                                
  5492.          WARN2("Not a gopher bookmark or menu file: %s",ep->dsname);            
  5493.          break;                                                                 
  5494.        }                                                                        
  5495.        ep->appending = TRUE;                                                    
  5496.      }                                                                          
  5497.      else {                                                                     
  5498.        ep->appending = FALSE;                                                   
  5499.      }                                                                          
  5500.    }                                                                            
  5501.    else if (ep->mode != JES) {                                                  
  5502.      if (do_warn) {                                                             
  5503.        if (TEST_IF_FILE_EXISTS(xfp,ggexdsn)) {                                  
  5504.          CLEANUP_IF_FILE_EXISTS(xfp);                                           
  5505.          xfp = NULL;                                                            
  5506.          if (GGMdispl(gp,"GGMPEXOW") > 0) {                                     
  5507.            WARN1("Operation cancelled, because you pressed END.");              
  5508.            break;                                                               
  5509.          }                                                                      
  5510.        }                                                                        
  5511.      }                                                                          
  5512.    }                                                                            
  5513.                                                                                 
  5514.    if (ep->mode == JES) {                                                       
  5515.      if (allocate_sysout(ep,&sys)) {                                            
  5516.        sprintf(ggexdsn,"dd:%s",ep->ddname);                                     
  5517.      }                                                                          
  5518.      else *ggexdsn = '\0';                                                      
  5519.    }                                                                            
  5520.                                                                                 
  5521.    if (ep->mode == PDS) {                                                       
  5522.      xfp = DUMMY_FILE_POINTER_FOR_PDS;                                          
  5523.      break;                                                                     
  5524.    }                                                                            
  5525.                                                                                 
  5526.    if (*ggexdsn) {                                                              
  5527.                                                                                 
  5528.      if (ep->mode == JES) {                                                     
  5529.        xfp = OPEN_SYSOUT_FILE(ggexdsn);                                         
  5530.      }                                                                          
  5531.      else {                                                                     
  5532.        xfp = OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(ggexdsn,ep->appending);         
  5533.      }                                                                          
  5534.                                                                                 
  5535.      if (!xfp) {                                                                
  5536. #ifdef SNSTCPIP                                                                 
  5537.        fprintf(stderr,"Open failure: errno=%d\n",GET_ERRNO);                    
  5538. #else                                                                           
  5539.        fprintf(stderr,"Open failure: errno=%d\n",errno);                        
  5540. #endif                                                                          
  5541.        perror(ggexdsn);                                                         
  5542.        ERR2("Cannot open data set %s.", ep->dsname);                            
  5543.      }                                                                          
  5544.    }                                                                            
  5545.  }                                                                              
  5546.                                                                                 
  5547.  (void)GGMispf(gp,"REMPOP");                                                    
  5548.                                                                                 
  5549.  return xfp;                                                                    
  5550.                                                                                 
  5551. }                                                                               
  5552.                                                                                 
  5553. ./   ADD NAME=GGMGETM                                                           
  5554.                                                                                 
  5555.  /********************************************************************/         
  5556.  /*                                                                  */         
  5557.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5558.  /*                                                                  */         
  5559.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5560.  /*                                                                  */         
  5561.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5562.  /* including the implied warranties of merchantability and fitness, */         
  5563.  /* are expressly denied.                                            */         
  5564.  /*                                                                  */         
  5565.  /* Provided this copyright notice is included, this software may    */         
  5566.  /* be freely distributed and not offered for sale.                  */         
  5567.  /*                                                                  */         
  5568.  /* Changes or modifications may be made and used only by the maker  */         
  5569.  /* of same, and not further distributed.  Such modifications should */         
  5570.  /* be mailed to the author for consideration for addition to the    */         
  5571.  /* software and incorporation in subsequent releases.               */         
  5572.  /*                                                                  */         
  5573.  /********************************************************************/         
  5574.                                                                                 
  5575. #pragma  csect(code,  "GG@GETM ")                                               
  5576. #pragma  csect(static,"GG$GETM ")                                               
  5577. #include "gg.h"                                                                 
  5578.                                                                                 
  5579. /****** Get memory. **************************************************/         
  5580.                                                                                 
  5581. void                                                                            
  5582. GGMgetm(gp,pointer,howmuch,whatfor)                                             
  5583. Rstruc ggcb    *gp;                                                             
  5584. char          **pointer;                                                        
  5585. int             howmuch;                                                        
  5586. char           *whatfor;                                                        
  5587. {                                                                               
  5588.                                                                                 
  5589.  *pointer = (char *)malloc(howmuch);                                            
  5590.                                                                                 
  5591.  if (*pointer == NULL) {                                                        
  5592.    fprintf(stderr,"GGMgetm: Cannot obtain %d bytes of memory for %s\n",         
  5593.                   howmuch,whatfor);                                             
  5594.  }                                                                              
  5595.  else if (gp->debug_file) {                                                     
  5596.    fprintf(gp->debug_file,"GGMgetm: got %d bytes of memory for %s\n",           
  5597.                            howmuch,whatfor);                                    
  5598.  }                                                                              
  5599.  return;                                                                        
  5600.                                                                                 
  5601. }                                                                               
  5602.                                                                                 
  5603. ./   ADD NAME=GGMGOFOR,SSI=01020021                                             
  5604.                                                                                 
  5605.  /********************************************************************/         
  5606.  /*                                                                  */         
  5607.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5608.  /*                                                                  */         
  5609.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5610.  /*                                                                  */         
  5611.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5612.  /* including the implied warranties of merchantability and fitness, */         
  5613.  /* are expressly denied.                                            */         
  5614.  /*                                                                  */         
  5615.  /* Provided this copyright notice is included, this software may    */         
  5616.  /* be freely distributed and not offered for sale.                  */         
  5617.  /*                                                                  */         
  5618.  /* Changes or modifications may be made and used only by the maker  */         
  5619.  /* of same, and not further distributed.  Such modifications should */         
  5620.  /* be mailed to the author for consideration for addition to the    */         
  5621.  /* software and incorporation in subsequent releases.               */         
  5622.  /*                                                                  */         
  5623.  /********************************************************************/         
  5624.                                                                                 
  5625. #pragma  csect(code,  "GG@GOFOR")                                               
  5626. #pragma  csect(static,"GG$GOFOR")                                               
  5627. #include "gg.h"                                                                 
  5628.                                                                                 
  5629. /********************************************************************/          
  5630.                                                                                 
  5631. static Bool                                                                     
  5632. connect_to_gopher_server(gp,sp,ip,is_cr_needed)                                 
  5633. Rstruc connection  *sp;                                                         
  5634. Rstruc ggcb        *gp;                                                         
  5635. Rstruc gopherinfo  *ip;                                                         
  5636. Fool                is_cr_needed;                                               
  5637. {                                                                               
  5638.  char              *lp;                                                         
  5639.  Bool               got_some;                                                   
  5640.                                                                                 
  5641.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  5642.  strcpy(gp->gopher_command,ip->path);   /* Specify command to issue */          
  5643.  gp->ginfo = ip;                                                                
  5644.  sp->receiving_text = FALSE;                                                    
  5645.                                                                                 
  5646.  if (!GGMconn(gp,sp)) return FALSE;   /* Connect to gopher server */            
  5647.                                                                                 
  5648.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  5649.                                                                                 
  5650.  GGMclrtx(gp,ip);                  /* Clear text */                             
  5651.                                                                                 
  5652.  sp->receiving_text = TRUE;                                                     
  5653.                                                                                 
  5654.  got_some = FALSE;                                                              
  5655.  do {                                                                           
  5656.    if (GGMgsrvl(gp,sp,&lp,is_cr_needed)) {  /* Get server line */               
  5657.      if (lp) {                                                                  
  5658.        got_some = TRUE;                                                         
  5659.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  5660.      }                                                                          
  5661.    }                                                                            
  5662.  } while (lp);                            /* until no more lines */             
  5663.                                                                                 
  5664.  if (!got_some) {                                                               
  5665.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  5666.    return FALSE;                                                                
  5667.  }                                                                              
  5668.                                                                                 
  5669.  return TRUE;                                                                   
  5670.                                                                                 
  5671. }                                                                               
  5672.                                                                                 
  5673. /****** Gopher it. ***************************************************/         
  5674.                                                                                 
  5675. Bool                                                                            
  5676. GGMgofor(gp,ip,as_file)                                                         
  5677. Rstruc ggcb        *gp;                                                         
  5678. Rstruc gopherinfo  *ip;                                                         
  5679. Fool                as_file;                                                    
  5680. {                                                                               
  5681.  Rstruc connection *sp;                                                         
  5682.  Bool               con;                                                        
  5683.  Bool               cr;                                                         
  5684.  Bool               rc;                                                         
  5685.  Bool             (*fun)(struct ggcb *,struct gopherinfo *,Fool);               
  5686.  char                    savebook[63];                                          
  5687.  sp = &gp->gopher_connection;                                                   
  5688.                                                                                 
  5689.    /* (1) send initial path string to initial host                              
  5690.     * (2) get back data from host                                               
  5691.     * (3) if it is a gopher directory, then do:                                 
  5692.     *      - display "table" of items                                           
  5693.     *      - for each item selected, call GGMgofor recursively                  
  5694.     *     else browse the file data                                             
  5695.     * (4) bye                                                                   
  5696.     */                                                                          
  5697.                                                                                 
  5698.  if (gp->debug_mode) {                                                          
  5699.    fprintf(gp->debug_file,"GGMgofor: type = %c\n",ip->type);                    
  5700.    fprintf(gp->debug_file,"GGMgofor: port = %d\n",ip->port);                    
  5701.    fprintf(gp->debug_file,"GGMgofor: path = %s\n",ip->path);                    
  5702.    fprintf(gp->debug_file,"GGMgofor: host = %s\n",ip->host);                    
  5703.    fprintf(gp->debug_file,"GGMgofor: desc = %s\n",ip->desc);                    
  5704.    fprintf(gp->debug_file,"GGMgofor: bmds = %s\n",ip->bmds);                    
  5705.  }                                                                              
  5706.                                                                                 
  5707.  switch (ip->type) {                                                            
  5708.    case GOPHER_FILE:     fun = GGMvtx;   con = TRUE;  cr = TRUE; break;         
  5709.    case GOPHER_DIRECTORY:fun = GGMdir;   con = TRUE;  cr = TRUE; break;         
  5710.    case GOPHER_TELNET:   fun = GGMtnet;  con = FALSE; cr = TRUE; break;         
  5711.    case GOPHER_TN3270:   fun = GGMtnet;  con = FALSE; cr = TRUE; break;         
  5712.    case GOPHER_WAIS:     fun = GGMwais;  con = FALSE; cr = TRUE; break;         
  5713.    case GOPHER_WHOIS:    fun = GGMwhois; con = FALSE; cr = TRUE; break;         
  5714.    case GOPHER_CSO:      fun = GGMcso;   con = FALSE; cr = FALSE;break;         
  5715.    default:                                                                     
  5716.         ERR2("Sorry, access via %s not supported", GGMtype(ip->type));          
  5717.         return FALSE;                                                           
  5718.  }                                                                              
  5719.                                                                                 
  5720.  if (con) {                                                                     
  5721.    if (!connect_to_gopher_server(gp,sp,ip,cr)) return FALSE;                    
  5722.  }                                                                              
  5723.                                                                                 
  5724.  /* Insure no connection is active once we do the real thing. */                
  5725.                                                                                 
  5726.  if (sp->connected_to_server) {                                                 
  5727.    (void)GGMdisc(gp,sp);     /* Disconnect from gopher server */                
  5728.  }                                                                              
  5729.                                                                                 
  5730.  strcpy(savebook,gp->current_bookmark_ds);                                      
  5731.  if (EQUAL(ip->host, LOCAL_HOST_FROB)) {                                        
  5732.    strncpy(gp->current_bookmark_ds,ip->path,sizeof(savebook));                  
  5733.  }                                                                              
  5734.  else {                                                                         
  5735.    strcpy(gp->current_bookmark_ds,"");                                          
  5736.  }                                                                              
  5737.                                                                                 
  5738.  rc = (fun)(gp,ip,as_file);                                                     
  5739.                                                                                 
  5740.  strcpy(gp->current_bookmark_ds,savebook);                                      
  5741.                                                                                 
  5742.  return rc;                                                                     
  5743.                                                                                 
  5744. }                                                                               
  5745.                                                                                 
  5746. ./   ADD NAME=GGMGSRVL,SSI=01000040                                             
  5747.                                                                                 
  5748.  /********************************************************************/         
  5749.  /*                                                                  */         
  5750.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5751.  /*                                                                  */         
  5752.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5753.  /*                                                                  */         
  5754.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5755.  /* including the implied warranties of merchantability and fitness, */         
  5756.  /* are expressly denied.                                            */         
  5757.  /*                                                                  */         
  5758.  /* Provided this copyright notice is included, this software may    */         
  5759.  /* be freely distributed and not offered for sale.                  */         
  5760.  /*                                                                  */         
  5761.  /* Changes or modifications may be made and used only by the maker  */         
  5762.  /* of same, and not further distributed.  Such modifications should */         
  5763.  /* be mailed to the author for consideration for addition to the    */         
  5764.  /* software and incorporation in subsequent releases.               */         
  5765.  /*                                                                  */         
  5766.  /********************************************************************/         
  5767.                                                                                 
  5768. #pragma  csect(code,  "GG@GSRVL")                                               
  5769. #pragma  csect(static,"GG$GSRVL")                                               
  5770. #include "gg.h"                                                                 
  5771.                                                                                 
  5772. /****** Input one character from the server. *************************/         
  5773.                                                                                 
  5774. static int                                                                      
  5775. socket_getchar(sp)                                                              
  5776. Rstruc connection *sp;                                                          
  5777. {                                                                               
  5778.  int         readrc;                                                            
  5779.                                                                                 
  5780.  if (sp->buf_index == -1 ||                                                     
  5781.      sp->buf_index >= sp->bytes_returned - 1) {                                 
  5782.    sp->buf_index = -1;                                                          
  5783.    if (sp->dont_read) return(SOCKET_NO_MORE);                                   
  5784.    else {                                                                       
  5785.      TCP_DEBUG_ON;                                                              
  5786.      readrc = read(sp->ns, sp->buf, READ_BYTES);                                
  5787.      TCP_DEBUG_OFF;                                                             
  5788.      if (readrc == -1) {                                                        
  5789.        sp->connection_broken = TRUE;                                            
  5790.        return SOCKET_GETCHAR_ERROR;                                             
  5791.      }                                                                          
  5792.      else if (readrc == 0) {                                                    
  5793.        sp->connection_broken = FALSE;                                           
  5794.        return SOCKET_READ_NOTHING;                                              
  5795.      }                                                                          
  5796.      else {                                                                     
  5797. #ifdef MVS                                                                      
  5798.        ASCII_TO_EBCDIC(sp->buf,readrc);                                         
  5799. #endif                                                                          
  5800.        sp->bytes_returned = readrc;                                             
  5801.      }                                                                          
  5802.    }                                                                            
  5803.  }                                                                              
  5804.  return sp->buf[++sp->buf_index];                                               
  5805. }                                                                               
  5806.                                                                                 
  5807. /****** Input one data line at a time from the server. ***************/         
  5808.                                                                                 
  5809. static enum socket_retval                                                       
  5810. socket_from_server(gp,sp)                                                       
  5811. Rstruc ggcb       *gp;                                                          
  5812. Rstruc connection *sp;                                                          
  5813. {                                                                               
  5814.  char             *s_buf;                                                       
  5815.  int               s_bytes;                                                     
  5816.  int               s_buf_index;                                                 
  5817.  int               character;                                                   
  5818.  int               previous_character;                                          
  5819.                                                                                 
  5820.  s_buf   = sp->server_buf;                                                      
  5821.  s_bytes = SERVER_BUF_MSGSIZE;                                                  
  5822.                                                                                 
  5823.  /* Get characters from the server until CRLF is reached. */                    
  5824.                                                                                 
  5825.  s_buf_index = 0;                                                               
  5826.  previous_character = -1;                                                       
  5827.  for (;;) {                                                                     
  5828.    character = socket_getchar(sp);                                              
  5829.    /*                                                                           
  5830.    if (character == LINE_FEED && previous_character == CARRIAGE_RETURN)         
  5831.       break;                                                                    
  5832.    */                                                                           
  5833.    if (character == LINE_FEED) break;                                           
  5834.    if (character == SOCKET_GETCHAR_ERROR)  return(SERVER_READ_ERROR);           
  5835.    if (character == SOCKET_NO_MORE)        return(SERVER_NO_MORE);              
  5836.    if (character == SOCKET_READ_NOTHING)   return(SERVER_READ_NOTHING);         
  5837.    previous_character = character;                                              
  5838.    if (s_buf_index >= s_bytes) {                                                
  5839.      fprintf(stderr,"Error: sp->server_buf overflowed.\n");                     
  5840.      fprintf(stderr,                                                            
  5841.              "More than %d bytes collected without CR/LF seen.\n",              
  5842.              s_bytes);                                                          
  5843.      if (gp->debug_file) {                                                      
  5844.        GGMdump(gp,"Data collected so far",sp->server_buf,s_bytes);              
  5845.      }                                                                          
  5846.      return(SERVER_BUFFER_ERROR);                                               
  5847.    }                                                                            
  5848.    if (character == '\0') {                                                     
  5849.      fprintf(stderr,                                                            
  5850. "Warning: null character found in data from server, changed to blank\n"         
  5851.             );                                                                  
  5852.      character = ' ';                                                           
  5853.    }                                                                            
  5854.    s_buf[s_buf_index++] = (unsigned char)character;                             
  5855.  }                                                                              
  5856.  s_buf[s_buf_index] = '\0';                                                     
  5857.  return(SERVER_READ_OK);                                                        
  5858. }                                                                               
  5859.                                                                                 
  5860. /****** Get server line. *********************************************/         
  5861.                                                                                 
  5862. Bool                                                                            
  5863. GGMgsrvl(gp,sp,pointer,is_cr_needed)                                            
  5864. Rstruc ggcb        *gp;                                                         
  5865. Rstruc connection  *sp;                                                         
  5866. char              **pointer;                                                    
  5867. Fool                is_cr_needed;                                               
  5868. {                                                                               
  5869.  char              *sbufp;                                                      
  5870.  char              *p;                                                          
  5871.  int                scan_count;                                                 
  5872.  Bool               something_to_print;                                         
  5873.  struct recvstruct *R;                                                          
  5874.                                                                                 
  5875.  *pointer = NULL;                                                               
  5876.                                                                                 
  5877.  /* If local mode, read from temporary file until EOF. */                       
  5878.                                                                                 
  5879.  if ((R=gp->recvp)) {                                                           
  5880.    if (!R->outfp) {                                                             
  5881.      CRIT1("Can't read data locally, non-socket not connected\n");              
  5882.      return FALSE;                                                              
  5883.    }                                                                            
  5884.    fgets(sp->server_buf, SERVER_BUF_MSGSIZE, R->outfp);                         
  5885.    if (ferror(R->outfp)) {                                                      
  5886.      CRIT1("Error reading local non-socket data\n");                            
  5887.      sp->time_to_go_home = TRUE;                                                
  5888.      return FALSE;                                                              
  5889.    }                                                                            
  5890.    if (feof(R->outfp)) return FALSE;                                            
  5891.    if ((p=strchr(sp->server_buf,'\n'))) *p = '\0';                              
  5892.    *pointer = sp->server_buf;                                                   
  5893.    return TRUE;                                                                 
  5894.  }                                                                              
  5895.                                                                                 
  5896.  if (!sp->receiving_text) return TRUE;                                          
  5897.                                                                                 
  5898.  if (sp->server_finished_replying) sp->dont_read = TRUE;                        
  5899.                                                                                 
  5900.  switch (socket_from_server(gp,sp)) {                                           
  5901.    case SERVER_READ_OK:      break;                                             
  5902.    case SERVER_READ_NOTHING: sp->time_to_go_home = TRUE;                        
  5903.                              break;                                             
  5904.    case SERVER_READ_ERROR:   ERR2(                                              
  5905.      "Lost server connection.  Failure reading data from server %s.",           
  5906.                                   gp->ggserver);                                
  5907.                              sp->time_to_go_home = TRUE;                        
  5908.                              break;                                             
  5909.    case SERVER_BUFFER_ERROR: ERR2(                                              
  5910.  "Read error.  No linefeed character found in data from server %s.",            
  5911.                                   gp->ggserver);                                
  5912.                              sp->time_to_go_home = TRUE;                        
  5913.                              break;                                             
  5914.    case SERVER_NO_MORE:      sp->server_has_something_pending = FALSE;          
  5915.                              break;                                             
  5916.  }                                                                              
  5917.                                                                                 
  5918.  if (sp->time_to_go_home) return FALSE;                                         
  5919.  if (sp->dont_read && !sp->server_has_something_pending) return TRUE;           
  5920.                                                                                 
  5921.  something_to_print = TRUE;                                                     
  5922.                                                                                 
  5923.  sbufp = sp->server_buf;                                                        
  5924.                                                                                 
  5925.  if (sp->sending_text) {                                                        
  5926.    if (*sbufp == '.') {                                                         
  5927.      switch (*(sbufp+1)) {                                                      
  5928.         case CARRIAGE_RETURN:                                                   
  5929.         case LINE_FEED:                                                         
  5930.         case '\0':                                                              
  5931.                   sp->server_finished_replying = TRUE;                          
  5932.                   something_to_print = FALSE;                                   
  5933.                   break;                                                        
  5934.         case '.':                                                               
  5935.                   break;                                                        
  5936.         default:                                                                
  5937.                   GGMdump(gp,"Warning, bad period in line from server",         
  5938.                           sbufp,strlen(sbufp));                                 
  5939.                   break;                                                        
  5940.      }                                                                          
  5941.    }                                                                            
  5942.  }                                                                              
  5943.                                                                                 
  5944.  sp->sending_text = TRUE;                                                       
  5945.                                                                                 
  5946.  if (something_to_print) {                                                      
  5947.    /* Last character of output buffer is a CR without LF. */                    
  5948.    p = sbufp + strlen(sbufp)-1;                                                 
  5949.    if (p >= sbufp) {                                                            
  5950.      if (*p == CARRIAGE_RETURN) *p = '\0';                                      
  5951.      else if (is_cr_needed) {                                                   
  5952.        /* Last character of output buffer had better be a LF. */                
  5953.        if (gp->debug_file) {                                                    
  5954.          fprintf(gp->debug_file,                                                
  5955.    "Warning: No carriage return in data from server (%d bytes):\n%s\n",         
  5956.                strlen(sbufp), sbufp);                                           
  5957.        }                                                                        
  5958.        CRIT2(                                                                   
  5959. "Carriage return expected but not seen in data from server %s.",                
  5960.              gp->ggserver);                                                     
  5961.      }                                                                          
  5962.      *(p+1) = '\0';                                                             
  5963.    }                                                                            
  5964.    *pointer = sbufp;                                                            
  5965.  }                                                                              
  5966.                                                                                 
  5967.  if (sp->time_to_go_home) return FALSE;                                         
  5968.  else return TRUE;                                                              
  5969. }                                                                               
  5970.                                                                                 
  5971. ./   ADD NAME=GGMIERR                                                           
  5972.                                                                                 
  5973.  /********************************************************************/         
  5974.  /*                                                                  */         
  5975.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5976.  /*                                                                  */         
  5977.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  5978.  /*                                                                  */         
  5979.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5980.  /* including the implied warranties of merchantability and fitness, */         
  5981.  /* are expressly denied.                                            */         
  5982.  /*                                                                  */         
  5983.  /* Provided this copyright notice is included, this software may    */         
  5984.  /* be freely distributed and not offered for sale.                  */         
  5985.  /*                                                                  */         
  5986.  /* Changes or modifications may be made and used only by the maker  */         
  5987.  /* of same, and not further distributed.  Such modifications should */         
  5988.  /* be mailed to the author for consideration for addition to the    */         
  5989.  /* software and incorporation in subsequent releases.               */         
  5990.  /*                                                                  */         
  5991.  /********************************************************************/         
  5992.                                                                                 
  5993. #pragma  csect(code,  "GG@IERR ")                                               
  5994. #pragma  csect(static,"GG$IERR ")                                               
  5995. #include "gg.h"                                                                 
  5996.                                                                                 
  5997. /****** ISPF error handler. ******************************************/         
  5998.                                                                                 
  5999. void                                                                            
  6000. GGMierr(gp)                                                                     
  6001. Rstruc ggcb *gp;                                                                
  6002. {                                                                               
  6003.  char        errbuf[] = "DISPLAY PANEL(ISPTERM)";                               
  6004.  int         errlen;                                                            
  6005.                                                                                 
  6006.  errlen = strlen(errbuf);                                                       
  6007.  switch (ISPEXEC(&errlen,errbuf)) {                                             
  6008.    case  0:                                                                     
  6009.    case  4:                                                                     
  6010.    case  8:                                                                     
  6011.            return;                                                              
  6012.    default:                                                                     
  6013.            fprintf(stderr,                                                      
  6014. "\n*** Severe ISPF error, cannot even display ISPTERM error panel.\n");         
  6015.            fprintf(stderr,                                                      
  6016. "\n*** Return code from ISPF service is %d\n",gp->ispfrc);                      
  6017.            return;                                                              
  6018.  }                                                                              
  6019. }                                                                               
  6020.                                                                                 
  6021. ./   ADD NAME=GGMIGET                                                           
  6022.                                                                                 
  6023.  /********************************************************************/         
  6024.  /*                                                                  */         
  6025.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6026.  /*                                                                  */         
  6027.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6028.  /*                                                                  */         
  6029.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6030.  /* including the implied warranties of merchantability and fitness, */         
  6031.  /* are expressly denied.                                            */         
  6032.  /*                                                                  */         
  6033.  /* Provided this copyright notice is included, this software may    */         
  6034.  /* be freely distributed and not offered for sale.                  */         
  6035.  /*                                                                  */         
  6036.  /* Changes or modifications may be made and used only by the maker  */         
  6037.  /* of same, and not further distributed.  Such modifications should */         
  6038.  /* be mailed to the author for consideration for addition to the    */         
  6039.  /* software and incorporation in subsequent releases.               */         
  6040.  /*                                                                  */         
  6041.  /********************************************************************/         
  6042.                                                                                 
  6043. #pragma  csect(code,  "GG@IGET ")                                               
  6044. #pragma  csect(static,"GG$IGET ")                                               
  6045. #include "gg.h"                                                                 
  6046.                                                                                 
  6047. /****** Retrieve the value of an ISPF variable into an integer. ******/         
  6048.                                                                                 
  6049. int                                                                             
  6050. GGMiget(gp,varname)                                                             
  6051. Rstruc ggcb *gp;                                                                
  6052. char        *varname;                                                           
  6053. {                                                                               
  6054.  char        varbuf[16];                                                        
  6055.  int         vcopy_length;                                                      
  6056.                                                                                 
  6057.  if (!strchr(varname,' ')) {                                                    
  6058.    fprintf(stderr,"GGMiget: no blank passed in var name\n");                    
  6059.    return FALSE;                                                                
  6060.  }                                                                              
  6061.                                                                                 
  6062.  vcopy_length = sizeof(varbuf);                                                 
  6063.                                                                                 
  6064.  gp->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");             
  6065.  switch (gp->ispfrc) {                                                          
  6066.    case  0:                                                                     
  6067.            varbuf[vcopy_length] = '\0';                                         
  6068.            return atoi(varbuf);                                                 
  6069.    case  8:                                                                     
  6070.            return 0;                                                            
  6071.    case 16:                                                                     
  6072.            fprintf(stderr,                                                      
  6073.                    "Error: ISPF variable buffer too short to get %s\n",         
  6074.                    varname);                                                    
  6075.            return 0;                                                            
  6076.    default:                                                                     
  6077.            GGMierr(gp);   /* handle ISPF error */                               
  6078.            return 0;                                                            
  6079.  }                                                                              
  6080. }                                                                               
  6081.                                                                                 
  6082. ./   ADD NAME=GGMINFO,SSI=01050051                                              
  6083.                                                                                 
  6084.  /********************************************************************/         
  6085.  /*                                                                  */         
  6086.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6087.  /*                                                                  */         
  6088.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6089.  /*                                                                  */         
  6090.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6091.  /* including the implied warranties of merchantability and fitness, */         
  6092.  /* are expressly denied.                                            */         
  6093.  /*                                                                  */         
  6094.  /* Provided this copyright notice is included, this software may    */         
  6095.  /* be freely distributed and not offered for sale.                  */         
  6096.  /*                                                                  */         
  6097.  /* Changes or modifications may be made and used only by the maker  */         
  6098.  /* of same, and not further distributed.  Such modifications should */         
  6099.  /* be mailed to the author for consideration for addition to the    */         
  6100.  /* software and incorporation in subsequent releases.               */         
  6101.  /*                                                                  */         
  6102.  /********************************************************************/         
  6103.                                                                                 
  6104. #pragma  csect(code,  "GG@INFO ")                                               
  6105. #pragma  csect(static,"GG$INFO ")                                               
  6106. #include "gg.h"                                                                 
  6107.                                                                                 
  6108.                                                                                 
  6109. /****** Gopher it. ***************************************************/         
  6110.                                                                                 
  6111. Bool                                                                            
  6112. GGMinfo(gp,ip)                                                                  
  6113. Rstruc ggcb        *gp;                                                         
  6114. Rstruc gopherinfo  *ip;                                                         
  6115. {                                                                               
  6116.  char               buf [513];                                                  
  6117.                                                                                 
  6118.  if (!ip) {                                                                     
  6119.    ERR1("Info is not available - this is not a Gopher item.");                  
  6120.    return FALSE;                                                                
  6121.  }                                                                              
  6122.                                                                                 
  6123.  GGMclrtx(gp,NULL);                                                             
  6124.                                                                                 
  6125.  sprintf(buf,"");                        GGMouttx(gp,buf,NULL);                 
  6126.  sprintf(buf,"Type=%c",ip->type);        GGMouttx(gp,buf,NULL);                 
  6127.  sprintf(buf,"Name=%s",ip->desc);        GGMouttx(gp,buf,NULL);                 
  6128.  sprintf(buf,"Path=%s",ip->path);        GGMouttx(gp,buf,NULL);                 
  6129.  sprintf(buf,"Host=%s",ip->host);        GGMouttx(gp,buf,NULL);                 
  6130.  sprintf(buf,"Port=%d",ip->port);        GGMouttx(gp,buf,NULL);                 
  6131.  sprintf(buf,"End");                     GGMouttx(gp,buf,NULL);                 
  6132.                                                                                 
  6133.  return TRUE;                                                                   
  6134. }                                                                               
  6135.                                                                                 
  6136. ./   ADD NAME=GGMISPF,SSI=01000057                                              
  6137.                                                                                 
  6138.  /********************************************************************/         
  6139.  /*                                                                  */         
  6140.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6141.  /*                                                                  */         
  6142.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6143.  /*                                                                  */         
  6144.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6145.  /* including the implied warranties of merchantability and fitness, */         
  6146.  /* are expressly denied.                                            */         
  6147.  /*                                                                  */         
  6148.  /* Provided this copyright notice is included, this software may    */         
  6149.  /* be freely distributed and not offered for sale.                  */         
  6150.  /*                                                                  */         
  6151.  /* Changes or modifications may be made and used only by the maker  */         
  6152.  /* of same, and not further distributed.  Such modifications should */         
  6153.  /* be mailed to the author for consideration for addition to the    */         
  6154.  /* software and incorporation in subsequent releases.               */         
  6155.  /*                                                                  */         
  6156.  /********************************************************************/         
  6157.                                                                                 
  6158. #pragma  csect(code,  "GG@ISPF ")                                               
  6159. #pragma  csect(static,"GG$ISPF ")                                               
  6160. #include "gg.h"                                                                 
  6161.                                                                                 
  6162. /****** Call ISPF service. *******************************************/         
  6163.                                                                                 
  6164. Bool                                                                            
  6165. GGMispf(gp,ispfbuf)                                                             
  6166. Rstruc ggcb *gp;                                                                
  6167. char        *ispfbuf;                                                           
  6168. {                                                                               
  6169.  int         ispflen = strlen(ispfbuf);                                         
  6170.                                                                                 
  6171. #ifndef ISPFV2                                                                  
  6172.  if (gp->test_mode) {                                                           
  6173. #endif                                                                          
  6174.    if (ispflen >= 6                                                             
  6175.       && (memcmp(ispfbuf,"ADDPOP",6) == 0                                       
  6176.        || memcmp(ispfbuf,"REMPOP",6) == 0)) {                                   
  6177.      gp->ispfrc = 0;                                                            
  6178.      return TRUE;                                                               
  6179.    }                                                                            
  6180. #ifndef ISPFV2                                                                  
  6181.  }                                                                              
  6182. #endif                                                                          
  6183.                                                                                 
  6184.  gp->ispfrc = ISPEXEC(&ispflen,ispfbuf);                                        
  6185.  if (gp->ispfrc > 8) {                                                          
  6186.                                                                                 
  6187.    /* Ignore ADDPOP and REMPOP errors, especially if they are due to            
  6188.       ISPF V3 not being active. */                                              
  6189.                                                                                 
  6190.    if (gp->ispfrc == 20                                                         
  6191.     && gp->debug_mode == FALSE                                                  
  6192.     && ispflen >= 6                                                             
  6193.     && (memcmp(ispfbuf,"ADDPOP",6) == 0                                         
  6194.      || memcmp(ispfbuf,"REMPOP",6) == 0)) {                                     
  6195.      return TRUE;                                                               
  6196.    }                                                                            
  6197.                                                                                 
  6198.    GGMierr(gp);             /* handle ISPF error */                             
  6199.    return FALSE;                                                                
  6200.  }                                                                              
  6201.  return TRUE;                                                                   
  6202. }                                                                               
  6203.                                                                                 
  6204. ./   ADD NAME=GGMIVGET                                                          
  6205.                                                                                 
  6206.  /********************************************************************/         
  6207.  /*                                                                  */         
  6208.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6209.  /*                                                                  */         
  6210.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6211.  /*                                                                  */         
  6212.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6213.  /* including the implied warranties of merchantability and fitness, */         
  6214.  /* are expressly denied.                                            */         
  6215.  /*                                                                  */         
  6216.  /* Provided this copyright notice is included, this software may    */         
  6217.  /* be freely distributed and not offered for sale.                  */         
  6218.  /*                                                                  */         
  6219.  /* Changes or modifications may be made and used only by the maker  */         
  6220.  /* of same, and not further distributed.  Such modifications should */         
  6221.  /* be mailed to the author for consideration for addition to the    */         
  6222.  /* software and incorporation in subsequent releases.               */         
  6223.  /*                                                                  */         
  6224.  /********************************************************************/         
  6225.                                                                                 
  6226. #pragma  csect(code,  "GG@IVGET")                                               
  6227. #pragma  csect(static,"GG$IVGET")                                               
  6228. #include "gg.h"                                                                 
  6229.                                                                                 
  6230. /****** Retrieve the value of an ISPF variable. **********************/         
  6231.                                                                                 
  6232. Bool                                                                            
  6233. GGMivget(gp,varname,varbuf,varbuflen)                                           
  6234. Rstruc ggcb *gp;                                                                
  6235. char        *varname;                                                           
  6236. char        *varbuf;                                                            
  6237. int          varbuflen;                                                         
  6238. {                                                                               
  6239.  int         vcopy_length;                                                      
  6240.                                                                                 
  6241.  if (!strchr(varname,' ')) {                                                    
  6242.    fprintf(stderr,"GGMivget: no blank passed in var name\n");                   
  6243.    return FALSE;                                                                
  6244.  }                                                                              
  6245.                                                                                 
  6246.  /*                                                                             
  6247.   * If varbuflen is negative, that means that the value is not to be            
  6248.   * treated as a C string, and the null character is not to be                  
  6249.   * appended to the resulting value.  This is used for hex values               
  6250.   * (like addresses) that are stored in ISPF table row variables.               
  6251.   */                                                                            
  6252.                                                                                 
  6253.  if (varbuflen < 0)  vcopy_length = -varbuflen;                                 
  6254.  else vcopy_length = varbuflen;                                                 
  6255.                                                                                 
  6256.  /* Note that on entry, vcopy_length is an integer that contains                
  6257.     the length of the buffer.  On return it is updated to the length            
  6258.     of the value returned.  Since we have to stick a null character             
  6259.     on the end of it for C, the actual buffer passed must be at least           
  6260.     one character longer than the length as defined to ISPF.                    
  6261.  */                                                                             
  6262.                                                                                 
  6263.  gp->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");             
  6264.  switch (gp->ispfrc) {                                                          
  6265.    case  0:                                                                     
  6266.            if (varbuflen >= 0)                                                  
  6267.               varbuf[vcopy_length] = '\0';                                      
  6268.            return TRUE;                                                         
  6269.    case  8:                                                                     
  6270.            strcpy(varbuf,"");                                                   
  6271.            return TRUE;                                                         
  6272.    case 16:                                                                     
  6273.            fprintf(stderr,                                                      
  6274.                    "Error: ISPF variable buffer too short to get %s\n",         
  6275.                    varname);                                                    
  6276.            return FALSE;                                                        
  6277.    default:                                                                     
  6278.            GGMierr(gp);   /* handle ISPF error */                               
  6279.            return FALSE;                                                        
  6280.  }                                                                              
  6281. }                                                                               
  6282.                                                                                 
  6283. ./   ADD NAME=GGMIVPUT                                                          
  6284.                                                                                 
  6285.  /********************************************************************/         
  6286.  /*                                                                  */         
  6287.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6288.  /*                                                                  */         
  6289.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6290.  /*                                                                  */         
  6291.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6292.  /* including the implied warranties of merchantability and fitness, */         
  6293.  /* are expressly denied.                                            */         
  6294.  /*                                                                  */         
  6295.  /* Provided this copyright notice is included, this software may    */         
  6296.  /* be freely distributed and not offered for sale.                  */         
  6297.  /*                                                                  */         
  6298.  /* Changes or modifications may be made and used only by the maker  */         
  6299.  /* of same, and not further distributed.  Such modifications should */         
  6300.  /* be mailed to the author for consideration for addition to the    */         
  6301.  /* software and incorporation in subsequent releases.               */         
  6302.  /*                                                                  */         
  6303.  /********************************************************************/         
  6304.                                                                                 
  6305. #pragma  csect(code,  "GG@IVPUT")                                               
  6306. #pragma  csect(static,"GG$IVPUT")                                               
  6307. #include "gg.h"                                                                 
  6308.                                                                                 
  6309. /****** Set the value of an ISPF variable. ***************************/         
  6310.                                                                                 
  6311. Bool                                                                            
  6312. GGMivput(gp,varname,varbuf,varlen)                                              
  6313. Rstruc ggcb *gp;                                                                
  6314. char        *varname;                                                           
  6315. char        *varbuf;                                                            
  6316. int          varlen;                                                            
  6317. {                                                                               
  6318.  int         vreplace_length;                                                   
  6319.                                                                                 
  6320.  vreplace_length = (varlen<0 ? strlen(varbuf) : varlen);                        
  6321.                                                                                 
  6322.  gp->ispfrc = ISPLINK("VREPLACE",varname,&vreplace_length,varbuf);              
  6323.  switch (gp->ispfrc) {                                                          
  6324.    case  0:                                                                     
  6325.            return TRUE;                                                         
  6326.    case 16:                                                                     
  6327.            fprintf(stderr,                                                      
  6328.                    "Error: ISPF variable buffer too short to put %s\n",         
  6329.                    varname);                                                    
  6330.            return FALSE;                                                        
  6331.    default:                                                                     
  6332.            GGMierr(gp);   /* handle ISPF error */                               
  6333.            return FALSE;                                                        
  6334.  }                                                                              
  6335. }                                                                               
  6336.                                                                                 
  6337. ./   ADD NAME=GGMMENU,SSI=01080012                                              
  6338.                                                                                 
  6339.  /********************************************************************/         
  6340.  /*                                                                  */         
  6341.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6342.  /*                                                                  */         
  6343.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6344.  /*                                                                  */         
  6345.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6346.  /* including the implied warranties of merchantability and fitness, */         
  6347.  /* are expressly denied.                                            */         
  6348.  /*                                                                  */         
  6349.  /* Provided this copyright notice is included, this software may    */         
  6350.  /* be freely distributed and not offered for sale.                  */         
  6351.  /*                                                                  */         
  6352.  /* Changes or modifications may be made and used only by the maker  */         
  6353.  /* of same, and not further distributed.  Such modifications should */         
  6354.  /* be mailed to the author for consideration for addition to the    */         
  6355.  /* software and incorporation in subsequent releases.               */         
  6356.  /*                                                                  */         
  6357.  /********************************************************************/         
  6358.                                                                                 
  6359. #pragma  csect(code,  "GG@MENU ")                                               
  6360. #pragma  csect(static,"GG$MENU ")                                               
  6361. #include "gg.h"                                                                 
  6362.                                                                                 
  6363. /****** Display Gopher menu in data set. *****************************/         
  6364.                                                                                 
  6365. Bool                                                                            
  6366. GGMmenu(gp,pp)                                                                  
  6367. Rstruc ggcb             *gp;                                                    
  6368. char                    *pp;                                                    
  6369. {                                                                               
  6370.  struct gopherinfo      *ip;                                                    
  6371.  struct gopherinfo      *saveip;                                                
  6372.  char                   *cp;                                                    
  6373.  Bool                    rc;                                                    
  6374.  char                    zprefix[9];                                            
  6375.  char                    temp[129];                                             
  6376.  char                    savebook[63];                                          
  6377.                                                                                 
  6378.  if (!*pp) {                                                                    
  6379.    ERR1("You must supply a data set name for a Gopher menu.");                  
  6380.    return FALSE;                                                                
  6381.  }                                                                              
  6382.                                                                                 
  6383.  if (strlen(pp) >= sizeof(temp)) {                                              
  6384.    ERR1("Gopher menu name too long");                                           
  6385.    return FALSE;                                                                
  6386.  }                                                                              
  6387.                                                                                 
  6388.  GETMAIN(ip, struct gopherinfo, 1, "menu gopherinfo struct");                   
  6389.  if (!ip) {                                                                     
  6390.    ERR2("Not enough memory to load Gopher menu %s",pp);                         
  6391.    return FALSE;                                                                
  6392.  }                                                                              
  6393.                                                                                 
  6394.  memset(ip,0,sizeof(struct gopherinfo));                                        
  6395.                                                                                 
  6396.                                                                                 
  6397.  copy_uppercase(temp,pp);                                                       
  6398.                                                                                 
  6399.  if (temp[0] == '\'') {                                                         
  6400.    strcpy(ip->path, temp+1);                                                    
  6401.    cp = &ip->path[strlen(ip->path)-1];                                          
  6402.    if (*cp == '\'') *cp = '\0';                                                 
  6403.  }                                                                              
  6404.  else {                                                                         
  6405.    GGMivget(gp,"ZPREFIX ",zprefix,sizeof(zprefix));                             
  6406.    if (!*zprefix)  sprintf(ip->path,"'%s'",pp);                                 
  6407.    else sprintf(ip->path,"%s.%s",zprefix,pp);                                   
  6408.  }                                                                              
  6409.                                                                                 
  6410.  ip->type = MENU;                                                               
  6411.  sprintf(ip->desc,"User menu %s",ip->path);                                     
  6412.  strcpy (ip->host, "-");                                                        
  6413.  ip->port = SERV_TCP_PORT;                                                      
  6414.                                                                                 
  6415.  saveip = gp->ginfo;                                                            
  6416.  gp->ginfo = ip;                                                                
  6417.  strcpy(savebook,gp->current_bookmark_ds);                                      
  6418.  strncpy(gp->current_bookmark_ds,ip->path,sizeof(savebook));                    
  6419.                                                                                 
  6420.  rc = GGMgofor(gp,ip,FALSE);                                                    
  6421.                                                                                 
  6422.  gp->ginfo = saveip;                                                            
  6423.  strcpy(gp->current_bookmark_ds,savebook);                                      
  6424.                                                                                 
  6425.  FREEMAIN(ip,"menu gopherinfo struct");                                         
  6426.                                                                                 
  6427.  return rc;                                                                     
  6428. }                                                                               
  6429.                                                                                 
  6430. ./   ADD NAME=GGMMTFER                                                          
  6431.                                                                                 
  6432.  /********************************************************************/         
  6433.  /*                                                                  */         
  6434.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6435.  /*                                                                  */         
  6436.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6437.  /*                                                                  */         
  6438.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6439.  /* including the implied warranties of merchantability and fitness, */         
  6440.  /* are expressly denied.                                            */         
  6441.  /*                                                                  */         
  6442.  /* Provided this copyright notice is included, this software may    */         
  6443.  /* be freely distributed and not offered for sale.                  */         
  6444.  /*                                                                  */         
  6445.  /* Changes or modifications may be made and used only by the maker  */         
  6446.  /* of same, and not further distributed.  Such modifications should */         
  6447.  /* be mailed to the author for consideration for addition to the    */         
  6448.  /* software and incorporation in subsequent releases.               */         
  6449.  /*                                                                  */         
  6450.  /********************************************************************/         
  6451.                                                                                 
  6452. #pragma  csect(code,  "GG@MTFER")                                               
  6453. #pragma  csect(static,"GG$MTFER")                                               
  6454. #include "gg.h"                                                                 
  6455.                                                                                 
  6456. /*********************************************************************/         
  6457.                                                                                 
  6458. void                                                                            
  6459. GGMmtfer(                                                                       
  6460.          int          retcode,                                                  
  6461.          char        *kind)                                                     
  6462. {                                                                               
  6463.  char    *ermsg;                                                                
  6464.                                                                                 
  6465.  switch (retcode) {                                                             
  6466.    case MTF_OK:                                                                 
  6467.         ermsg = NULL;                                                           
  6468.         break;                                                                  
  6469.    case EINACTIVE:                                                              
  6470.         ermsg = "MTF is inactive";                                              
  6471.         break;                                                                  
  6472.    case ESUBCALL:                                                               
  6473.         ermsg = "The MTF call was issued from a subtask";                       
  6474.         break;                                                                  
  6475.    case EWRONGOS:                                                               
  6476.         ermsg = "MTF is not supported under CMS, IMS, CICS, or DB2";            
  6477.         break;                                                                  
  6478.    case EACTIVE:                                                                
  6479.         ermsg = "MTF has already been initialized and is active";               
  6480.         break;                                                                  
  6481.    case ENAME2LNG:                                                              
  6482.         ermsg = "The parallel module name is longer than 8 characters";         
  6483.         break;                                                                  
  6484.    case ETASKNUM:                                                               
  6485.         ermsg = "The number of tasks specified is invalid";                     
  6486.         break;                                                                  
  6487.    case ENOMEM:                                                                 
  6488.         ermsg = "Insufficient storage for MTF internal areas";                  
  6489.         break;                                                                  
  6490.    case EMODFIND:                                                               
  6491.         ermsg = "The parallel load module was not found";                       
  6492.         break;                                                                  
  6493.    case EMODREAD:                                                               
  6494.         ermsg = "The parallel load module was not sucessfully read";            
  6495.         break;                                                                  
  6496.    case EMODFMT:                                                                
  6497.         ermsg = "The parallel load module format is invalid";                   
  6498.         break;                                                                  
  6499.    case EAUTOALC:                                                               
  6500.         ermsg = "Automatic allocation of standard stream DD failed";            
  6501.         break;                                                                  
  6502.    case ETASKFAIL:                                                              
  6503.         ermsg = "The attempt to attach task(s) has failed";                     
  6504.         break;                                                                  
  6505.    case ETASKABND:                                                              
  6506.         ermsg = "One or more subtasks have abnormally terminated";              
  6507.         break;                                                                  
  6508.    case EBADLNKG:                                                               
  6509.         ermsg = "TSCHED has been invoked via invalid linkage";                  
  6510.         break;                                                                  
  6511.    case ETASKID:                                                                
  6512.         ermsg = "The task ID specified is not valid";                           
  6513.         break;                                                                  
  6514.    case EENTRY:                                                                 
  6515.         ermsg = "The parallel function was not in the parallel module";         
  6516.         break;                                                                  
  6517.    default:                                                                     
  6518.         ermsg = "Unknown MTF error";                                            
  6519.         break;                                                                  
  6520.  }                                                                              
  6521.                                                                                 
  6522.  if (ermsg) {                                                                   
  6523.    fprintf(stderr,"GGSERVER: %s error code %d:\n %s\n",                         
  6524.                   kind, retcode, ermsg);                                        
  6525.  }                                                                              
  6526.                                                                                 
  6527.  return;                                                                        
  6528.                                                                                 
  6529. }                                                                               
  6530.                                                                                 
  6531. ./   ADD NAME=GGMOUTS                                                           
  6532.                                                                                 
  6533.  /********************************************************************/         
  6534.  /*                                                                  */         
  6535.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6536.  /*                                                                  */         
  6537.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6538.  /* including the implied warranties of merchantability and fitness, */         
  6539.  /* are expressly denied.                                            */         
  6540.  /*                                                                  */         
  6541.  /* Provided this copyright notice is included, this software may    */         
  6542.  /* be freely distributed and not offered for sale.                  */         
  6543.  /*                                                                  */         
  6544.  /* Changes or modifications may be made and used only by the maker  */         
  6545.  /* of same, and not further distributed.  Such modifications should */         
  6546.  /* be mailed to the author for consideration for addition to the    */         
  6547.  /* software and incorporation in subsequent releases.               */         
  6548.  /*                                                                  */         
  6549.  /********************************************************************/         
  6550.                                                                                 
  6551. #pragma  csect(code,  "GG@MOUTS")                                               
  6552. #pragma  csect(static,"GG$MOUTS")                                               
  6553.                                                                                 
  6554. #include "gg.h"                                                                 
  6555. /*                                                                              
  6556.  ***********************************************************************        
  6557.  *                                                                     *        
  6558.  * This is a Gopher server routine that outputs data to a socket.      *        
  6559.  *                                                                     *        
  6560.  * If the "socket" is actually a file pointer, then output is          *        
  6561.  * written to the file pointer.                                        *        
  6562.  *                                                                     *        
  6563.  ***********************************************************************        
  6564.  */                                                                             
  6565.                                                                                 
  6566. /*=================================================================*/           
  6567.                                                                                 
  6568. Bool                                                                            
  6569. GGMouts(struct recvstruct *R,                                                   
  6570.         char              *text)                                                
  6571. {                                                                               
  6572.  int                len;                                                        
  6573.  int                reallen;                                                    
  6574.  Bool               rc;                                                         
  6575.  char               outbuf[515];  /* hold an output character string */         
  6576.                                                                                 
  6577.  if (R->outfp) {                    /* if using non-socket interface */         
  6578.    if (fputs(text,R->outfp) < 0) {                                              
  6579.      fprintf(stderr,"Error writing to output file\n");                          
  6580.      return FALSE;                                                              
  6581.    }                                                                            
  6582.    if (fputc('\n',R->outfp) < 0) {                                              
  6583.      fprintf(stderr,"Error writing to output file\n");                          
  6584.      return FALSE;                                                              
  6585.    }                                                                            
  6586.    return TRUE;                                                                 
  6587.  }                                                                              
  6588.                                                                                 
  6589.  if (text == NULL) {                                                            
  6590.    outbuf[0] = '.';                                                             
  6591.    len = 1;                                                                     
  6592.  }                                                                              
  6593.  else {                                                                         
  6594.    len = strlen(text);                                                          
  6595.    if (len >= sizeof(outbuf)-3) len = sizeof(outbuf)-3;                         
  6596.    if (text[0] == '.') {                                                        
  6597.      outbuf[0] = '.';                                                           
  6598.      memcpy(outbuf+1,text,len);                                                 
  6599.      len++;                                                                     
  6600.    }                                                                            
  6601.    else {                                                                       
  6602.      memcpy(outbuf,text,len);                                                   
  6603.    }                                                                            
  6604.  }                                                                              
  6605.  outbuf[len  ] = CARRIAGE_RETURN;                                               
  6606.  outbuf[len+1] = LINE_FEED;                                                     
  6607.  outbuf[len+2] = '\0';                                                          
  6608.  reallen = len + 2;                                                             
  6609.                                                                                 
  6610. #ifdef SNSTCPIP                                                                 
  6611.  EBCDIC_TO_ASCII(outbuf,reallen);                                               
  6612. #else                                                                           
  6613.  ebdtoasc(outbuf);                                                              
  6614. #endif                                                                          
  6615.                                                                                 
  6616.  rc = TRUE;                                                                     
  6617.                                                                                 
  6618.  if (R->outlen + reallen > sizeof(R->sockbuf)) {                                
  6619.                                                                                 
  6620.    if (write(R->sockfd,R->sockbuf,R->outlen) < 0) {                             
  6621.      REPORT_TCP_ERROR("SEND");                                                  
  6622.      rc = FALSE;                                                                
  6623.    }                                                                            
  6624.    R->outlen = 0;                                                               
  6625.  }                                                                              
  6626.                                                                                 
  6627.  memcpy(R->sockbuf + R->outlen, outbuf, reallen);                               
  6628.  R->outlen += reallen;                                                          
  6629.                                                                                 
  6630.  if (text == NULL) {  /* flush socket */                                        
  6631.    if (write(R->sockfd,R->sockbuf,R->outlen) < 0) {                             
  6632.      REPORT_TCP_ERROR("SEND");                                                  
  6633.      rc = FALSE;                                                                
  6634.    }                                                                            
  6635.  }                                                                              
  6636.  return rc;                                                                     
  6637. }                                                                               
  6638.                                                                                 
  6639. ./   ADD NAME=GGMOUTTX                                                          
  6640.                                                                                 
  6641.  /********************************************************************/         
  6642.  /*                                                                  */         
  6643.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6644.  /*                                                                  */         
  6645.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6646.  /*                                                                  */         
  6647.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6648.  /* including the implied warranties of merchantability and fitness, */         
  6649.  /* are expressly denied.                                            */         
  6650.  /*                                                                  */         
  6651.  /* Provided this copyright notice is included, this software may    */         
  6652.  /* be freely distributed and not offered for sale.                  */         
  6653.  /*                                                                  */         
  6654.  /* Changes or modifications may be made and used only by the maker  */         
  6655.  /* of same, and not further distributed.  Such modifications should */         
  6656.  /* be mailed to the author for consideration for addition to the    */         
  6657.  /* software and incorporation in subsequent releases.               */         
  6658.  /*                                                                  */         
  6659.  /********************************************************************/         
  6660.                                                                                 
  6661. #pragma  csect(code,  "GG@OUTTX")                                               
  6662. #pragma  csect(static,"GG$OUTTX")                                               
  6663. #include "gg.h"                                                                 
  6664.                                                                                 
  6665. /****** Output a line of text retrieved from the server. *************/         
  6666.                                                                                 
  6667. struct textline *                                                               
  6668. GGMouttx(gp,line,ip)                                                            
  6669. Rstruc ggcb         *gp;                                                        
  6670. char                *line;                                                      
  6671. Rstruc gopherinfo   *ip;                                                        
  6672.                                                                                 
  6673. {                                                                               
  6674.  struct texthdr     *thp;                                                       
  6675.  struct textline    *tp;                                                        
  6676.  short              line_length;                                                
  6677.  short              total_text_length;                                          
  6678.  short              tab_expansion_length;                                       
  6679.  Bool               tabs_present;                                               
  6680.  char              *p;                                                          
  6681.  char              *q;                                                          
  6682.  char              *t;                                                          
  6683.  int                e;                                                          
  6684.  int                u;                                                          
  6685.                                                                                 
  6686.  static char        tab_expansion_buffer[8*TEXT_BYTES];                         
  6687.                                                                                 
  6688.  thp = (ip ? &ip->thdr : &gp->thdr);                                            
  6689.                                                                                 
  6690.  /* If line starts with double period, make it a single period. */              
  6691.                                                                                 
  6692.  if (ip && memcmp(line,"..",2) == 0) line++;                                    
  6693.                                                                                 
  6694.  /* Add this line to the current queue of server text lines. */                 
  6695.                                                                                 
  6696.  /* First, expand tabs in the line. */                                          
  6697.                                                                                 
  6698.  line_length = strlen(line);                                                    
  6699.  t = strchr(line,'\t');                                                         
  6700.  if (t == NULL) {                                                               
  6701.    tabs_present = FALSE;                                                        
  6702.    total_text_length = line_length + 1;                                         
  6703.  }                                                                              
  6704.  else {                                   /* expand tabs */                     
  6705.    tabs_present = TRUE;                                                         
  6706.    p = line;                                                                    
  6707.    q = line + line_length;                                                      
  6708.    e = 0;                                                                       
  6709.    memset(tab_expansion_buffer,' ',sizeof(tab_expansion_buffer));               
  6710.    while (TRUE) {                                                               
  6711.      u = t-p;                                                                   
  6712.      if (u > 0) {                                                               
  6713.        memcpy(tab_expansion_buffer+e,p,u);                                      
  6714.        e += u;                                                                  
  6715.      }                                                                          
  6716.      if (t == q) break;                                                         
  6717.      e = e / 8 * 8 + 8;                                                         
  6718.      p = t+1;                                                                   
  6719.      t = strchr(p,'\t');                                                        
  6720.      if (t == NULL) t = q;                                                      
  6721.    }                                                                            
  6722.    tab_expansion_length = e;                                                    
  6723.    tab_expansion_buffer[tab_expansion_length] = '\0';                           
  6724.    total_text_length = line_length + tab_expansion_length + 1;                  
  6725.  }                                                                              
  6726.                                                                                 
  6727.  GETMAIN(tp, char, offsetof(struct textline, text) + total_text_length,         
  6728.                    "text line");                                                
  6729.                                                                                 
  6730.  if (tp == NULL) {                                                              
  6731.    ERR1("There is not enough virtual storage to process server text.");         
  6732.    return NULL;                                                                 
  6733.  }                                                                              
  6734.                                                                                 
  6735.  tp->next = NULL;                                                               
  6736.  tp->text_length = line_length;                                                 
  6737.  strcpy(tp->text,line);                                                         
  6738.  if (tabs_present) {                                                            
  6739.    tp->tab_expanded_text_length = tab_expansion_length;                         
  6740.    tp->tab_expanded_text = tp->text + line_length;                              
  6741.    strcpy(tp->tab_expanded_text,tab_expansion_buffer);                          
  6742.  }                                                                              
  6743.  else {                                                                         
  6744.    tp->tab_expanded_text_length = line_length;                                  
  6745.    tp->tab_expanded_text = tp->text;                                            
  6746.  }                                                                              
  6747.                                                                                 
  6748.  if (thp->last_text_line == NULL) {                                             
  6749.    thp->first_text_line   = tp;                                                 
  6750.    thp->text_body_line    = tp;                                                 
  6751.    thp->current_text_line = tp;                                                 
  6752.  }                                                                              
  6753.  else thp->last_text_line->next = tp;                                           
  6754.                                                                                 
  6755.  thp->last_text_line = tp;                                                      
  6756.  thp->text_line_count++;                                                        
  6757.                                                                                 
  6758.  if (thp->text_max_length < tp->text_length)                                    
  6759.      thp->text_max_length = tp->text_length;                                    
  6760.  if (thp->text_max_tab_expanded_length < tp->tab_expanded_text_length)          
  6761.      thp->text_max_tab_expanded_length = tp->tab_expanded_text_length;          
  6762.                                                                                 
  6763.  return tp;                                                                     
  6764.                                                                                 
  6765. }                                                                               
  6766.                                                                                 
  6767. ./   ADD NAME=GGMPMSG                                                           
  6768.                                                                                 
  6769.  /********************************************************************/         
  6770.  /*                                                                  */         
  6771.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6772.  /*                                                                  */         
  6773.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6774.  /*                                                                  */         
  6775.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6776.  /* including the implied warranties of merchantability and fitness, */         
  6777.  /* are expressly denied.                                            */         
  6778.  /*                                                                  */         
  6779.  /* Provided this copyright notice is included, this software may    */         
  6780.  /* be freely distributed and not offered for sale.                  */         
  6781.  /*                                                                  */         
  6782.  /* Changes or modifications may be made and used only by the maker  */         
  6783.  /* of same, and not further distributed.  Such modifications should */         
  6784.  /* be mailed to the author for consideration for addition to the    */         
  6785.  /* software and incorporation in subsequent releases.               */         
  6786.  /*                                                                  */         
  6787.  /********************************************************************/         
  6788.                                                                                 
  6789. #define  SUPPRESS_V_DECLARATION                                                 
  6790. #pragma  csect(code,  "GG@PMSG ")                                               
  6791. #pragma  csect(static,"GG$PMSG ")                                               
  6792. #include "gg.h"                                                                 
  6793.                                                                                 
  6794. /****** Set an ISPF message, or write to SYSOUT if batch mode. *******/         
  6795.                                                                                 
  6796. void                                                                            
  6797. GGMpmsg(gp,msgtype,msghelp,msgformat) /* also ... for sprintf args */           
  6798. Rstruc ggcb *gp;                                                                
  6799. int          msgtype;                                                           
  6800. char        *msghelp;                                                           
  6801. char        *msgformat;                                                         
  6802. {                                                                               
  6803.  va_list     argp;                                                              
  6804.  char       *cp;                                                                
  6805.  char        zerrsm    [25];                                                    
  6806.  char        zerrhm     [9];                                                    
  6807.  char        zerralrm   [4];                                                    
  6808.  char        zerrlm   [ZERRLM_SIZE];                                            
  6809.  char        buf      [257];                                                    
  6810.                                                                                 
  6811.  va_start(argp,msgformat);                                                      
  6812.  vsprintf(buf,msgformat,argp);                                                  
  6813.  va_end(argp);                                                                  
  6814.                                                                                 
  6815.  cp = strchr(buf,';');                                                          
  6816.  if (cp) {                                                                      
  6817.   *cp = '\0';                                                                   
  6818.   strncpy(zerrsm,buf, sizeof(zerrsm));                                          
  6819.   strncpy(zerrlm,cp+1,sizeof(zerrlm));                                          
  6820.  }                                                                              
  6821.  else {                                                                         
  6822.   strcpy(zerrsm,"");                                                            
  6823.   strncpy(zerrlm,buf,sizeof(zerrlm));                                           
  6824.  }                                                                              
  6825.                                                                                 
  6826.  zerrsm[sizeof(zerrsm)-1] = '\0';                                               
  6827.  zerrlm[sizeof(zerrlm)-1] = '\0';                                               
  6828.                                                                                 
  6829.  if (msghelp) strcpy(zerrhm, msghelp);                                          
  6830.  else         strcpy(zerrhm, "*"    );                                          
  6831.                                                                                 
  6832.  switch (msgtype) {                                                             
  6833.    case NOTIFY_MSG:    strcpy(zerralrm,"NO "); break;                           
  6834.    case WARNING_MSG:                                                            
  6835.    case CRITICAL_MSG:                                                           
  6836.    default:            strcpy(zerralrm,"YES"); break;                           
  6837.  }                                                                              
  6838.                                                                                 
  6839.  (void)GGMivput(gp,"ZERRSM ",  zerrsm,   -1);                                   
  6840.  (void)GGMivput(gp,"ZERRLM ",  zerrlm,   -1);                                   
  6841.  (void)GGMivput(gp,"ZERRHM ",  zerrhm,   -1);                                   
  6842.  (void)GGMivput(gp,"ZERRALRM ",zerralrm, -1);                                   
  6843.                                                                                 
  6844.  gp->setmsg = TRUE;                                                             
  6845.                                                                                 
  6846.  return;                                                                        
  6847. }                                                                               
  6848.                                                                                 
  6849. ./   ADD NAME=GGMPROC,SSI=01030021                                              
  6850.                                                                                 
  6851.  /********************************************************************/         
  6852.  /*                                                                  */         
  6853.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  6854.  /*                                                                  */         
  6855.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6856.  /* including the implied warranties of merchantability and fitness, */         
  6857.  /* are expressly denied.                                            */         
  6858.  /*                                                                  */         
  6859.  /* Provided this copyright notice is included, this software may    */         
  6860.  /* be freely distributed and not offered for sale.                  */         
  6861.  /*                                                                  */         
  6862.  /* Changes or modifications may be made and used only by the maker  */         
  6863.  /* of same, and not further distributed.  Such modifications should */         
  6864.  /* be mailed to the author for consideration for addition to the    */         
  6865.  /* software and incorporation in subsequent releases.               */         
  6866.  /*                                                                  */         
  6867.  /********************************************************************/         
  6868.                                                                                 
  6869. #pragma  csect(code,  "GG@MPROC")                                               
  6870. #pragma  csect(static,"GG$MPROC")                                               
  6871.                                                                                 
  6872. #pragma  linkage(IRXEXEC,OS)                                                    
  6873.                                                                                 
  6874. #include "gg.h"                                                                 
  6875.                                                                                 
  6876. /**********************************************************************         
  6877.  *                                                                    *         
  6878.  * Changes: 02/17/93 Fixed memcmp logic in append-domain-name code.   *         
  6879.  *                                                                    *         
  6880.  **********************************************************************/        
  6881.                                                                                 
  6882. /*=================================================================*/           
  6883.                                                                                 
  6884. /*******************************************************************/           
  6885. /*   This routine cleans up a token.  It converts all chars to     */           
  6886. /*   upper case and removes any leading spaces. Note that the      */           
  6887. /*   string is assumed to be null terminated.                      */           
  6888. /*                                                                 */           
  6889. /*       INPUT    token          pointer to token string.          */           
  6890. /*       OUTPUT   *token         string upcased, blanks removed.   */           
  6891. /*******************************************************************/           
  6892.                                                                                 
  6893. static char *                                                                   
  6894. uppercase_and_trim_leading_space(char *token)                                   
  6895. {                                                                               
  6896.                                                                                 
  6897.  uppercase_in_place(token);                                                     
  6898.                                                                                 
  6899.  return token + strspn(token," ");                                              
  6900. };                                                                              
  6901.                                                                                 
  6902. /*=================================================================*/           
  6903.                                                                                 
  6904. /****************************************************/                          
  6905. /* This routine "cleans" a string by removing the   */                          
  6906. /* leading spaces and trailing spaces+non-printable */                          
  6907. /* characters.                                      */                          
  6908. /****************************************************/                          
  6909.                                                                                 
  6910. static char *                                                                   
  6911. trim_leading_and_trailing_space(char *string)                                   
  6912. {                                                                               
  6913. char *str;                                                                      
  6914. char *ptr;                                                                      
  6915.                                                                                 
  6916.  /*  first clean up the beginning of the string... */                           
  6917.                                                                                 
  6918.  str = string + strspn(string," \t");                                           
  6919.                                                                                 
  6920.  /*    now look at the end of the string... */                                  
  6921.                                                                                 
  6922.  ptr = str+strlen(str)-1;                                                       
  6923.  while (!isgraph(*ptr) && ptr >=str) ptr--;                                     
  6924.  *(ptr+1)=0;                                                                    
  6925.                                                                                 
  6926.  return str;                                                                    
  6927. }                                                                               
  6928.                                                                                 
  6929. /*=================================================================*/           
  6930.                                                                                 
  6931. /****************************************************/                          
  6932. /* This routine "cleans" an output line by removing */                          
  6933. /* trailing spaces and non-printable characters.    */                          
  6934. /****************************************************/                          
  6935.                                                                                 
  6936. static void                                                                     
  6937. trim_trailing_space(char *string)                                               
  6938. {                                                                               
  6939.  char *ptr;                                                                     
  6940.                                                                                 
  6941.  ptr = string;                                                                  
  6942.                                                                                 
  6943.  /*  look at the end of the string... */                                        
  6944.                                                                                 
  6945.  ptr = string+strlen(string)-1;                                                 
  6946.  while (isgraph(*ptr)==0 && ptr >=string) ptr--;                                
  6947.  *(ptr+1)=0;                                                                    
  6948. }                                                                               
  6949.                                                                                 
  6950. /*=================================================================*/           
  6951.                                                                                 
  6952. static void                                                                     
  6953. gbarf(struct recvstruct *R,                                                     
  6954.       char              *message)                                               
  6955. {                                                                               
  6956.  char        temp[257];                                                         
  6957.                                                                                 
  6958.  /* the number should be 3 (ERROR) but some clients may not show it             
  6959.   *             |                                                               
  6960.   *             |                                                               
  6961.   *             |                                                               
  6962.   *             V                                                               
  6963.   */                                                                            
  6964.  sprintf(temp, "1Sorry, %s.\t0\t0\t0", message);                                
  6965.                                                                                 
  6966.  (void)GGMouts(R,temp);                                                         
  6967.                                                                                 
  6968.  return;                                                                        
  6969. }                                                                               
  6970.                                                                                 
  6971. /*=================================================================*/           
  6972.                                                                                 
  6973. static Bool                                                                     
  6974. insure_my_name(struct recvstruct *R)                                            
  6975. {                                                                               
  6976.  int                hostlen;                                                    
  6977.  int                domslen;                                                    
  6978.                                                                                 
  6979.  /* Determine the local path name, if not already set. */                       
  6980.                                                                                 
  6981.  if (!*R->myname) {                                                             
  6982.    if (gethostname(R->myname,MAXHOSTNAMELEN) < 0) {                             
  6983.      fprintf(stderr,"GOPHER:gethostname() failed, can't get my name\n");        
  6984.      gbarf(R,"the GOPHER server had an attack of amnesia");                     
  6985.      return FALSE;                                                              
  6986.    }                                                                            
  6987.                                                                                 
  6988. #ifdef APPEND_DOMAIN_NAME_TO_SELF                                               
  6989.                                                                                 
  6990.    hostlen = strlen(R->myname);                                                 
  6991.    domslen = strlen(R->mydomain);                                               
  6992.    if (hostlen <= domslen ||                                                    
  6993.       memcmp(R->myname+hostlen-domslen, R->mydomain, domslen)) {                
  6994.      strncat(R->myname, R->mydomain, domslen);                                  
  6995.    }                                                                            
  6996.                                                                                 
  6997. #endif                                                                          
  6998.                                                                                 
  6999.    uppercase_in_place(R->myname);                                               
  7000.                                                                                 
  7001.    /* fprintf(stderr,"Local hostname set to '%s'\n",R->myname); */              
  7002.                                                                                 
  7003.  }                                                                              
  7004.                                                                                 
  7005.  return TRUE;                                                                   
  7006.                                                                                 
  7007. }                                                                               
  7008.                                                                                 
  7009. /*=================================================================*/           
  7010.                                                                                 
  7011. static Bool                                                                     
  7012. authorized_file(struct recvstruct *R)                                           
  7013. {                                                                               
  7014.  char    *cp;                                                                   
  7015.  FILE    *afp;                                                                  
  7016.  int      n;                                                                    
  7017.  int      hostcount;                                                            
  7018.  Bool     rc;                                                                   
  7019.  char     filetest[RBUFSIZE];                                                   
  7020.  char     accline [RBUFSIZE];                                                   
  7021.  char     accfile [RBUFSIZE];                                                   
  7022.  char     acchost [RBUFSIZE];                                                   
  7023.                                                                                 
  7024.  /* If non-socket interface, bypass the authorization check. */                 
  7025.                                                                                 
  7026.  if (R->outfp) return TRUE;                                                     
  7027.                                                                                 
  7028.  /* Check that the server is allowed to return data from the file               
  7029.   * specified in R->fileptr.  Note that this could be the name of               
  7030.   * an exec.  The name will be (dataset), EXEC:execname, or DD:file             
  7031.   * - we look at only the first part, whitespace-delimited.                     
  7032.   * Entries in the file authorization table look as above.                      
  7033.   */                                                                            
  7034.                                                                                 
  7035.  rc = FALSE;                                                                    
  7036.  filetest[0] = '\0';                                                            
  7037.  sscanf(R->fileptr,"%s",filetest);                                              
  7038.                                                                                 
  7039.  /* Read authorization file. */                                                 
  7040.                                                                                 
  7041.  afp = fopen(ACCESS_TABLE,"r");                                                 
  7042.  if (!afp) {                                                                    
  7043.    perror(ACCESS_TABLE);                                                        
  7044.    fflush(stderr);                                                              
  7045.    return FALSE;                                                                
  7046.  }                                                                              
  7047.                                                                                 
  7048.  for (;;) {                                                                     
  7049.    fgets(accline, sizeof(accline), afp);                                        
  7050.    if (ferror(afp)) {                                                           
  7051.      fprintf(stderr,"Error reading access table %s\n",ACCESS_TABLE);            
  7052.      fflush(stderr);                                                            
  7053.      break;                                                                     
  7054.    }                                                                            
  7055.    if (feof(afp)) break;                                                        
  7056.    /* format of line is: filename machine(s) */                                 
  7057.    uppercase_in_place(accline);                                                 
  7058.    cp = accline;                      /* Start scan pointer         */          
  7059.    *accfile = '\0';                   /* Clear access file name     */          
  7060.    sscanf(cp,"%s %n",accfile,&n);     /* Get file name, bump scan   */          
  7061.    if (!strcmp(filetest,accfile)) {   /* If file name matches       */          
  7062.      hostcount = 0;                   /* Clear access host count    */          
  7063.      for (;;) {                       /* Loop over access host ids  */          
  7064.        cp += n;                       /* Bump to next word in file  */          
  7065.        *acchost = '\0';               /* Clear word before scanf    */          
  7066.        sscanf(cp,"%s %n",acchost,&n); /* Get next word, bump scan   */          
  7067.        if (!*acchost) break;          /* exit loop if no more hosts */          
  7068.        hostcount++;                   /* increment access host count*/          
  7069.        if (!strcmp(R->hostname,acchost)                                         
  7070.         || !strcmp(R->hosttest,acchost)) { /* if hostname matches */            
  7071.          rc = TRUE;                        /* access is allowed   */            
  7072.          break;                                                                 
  7073.        }                                                                        
  7074.      }                                                                          
  7075.      if (!rc) {                       /* If no matching host found  */          
  7076.        if (hostcount == 0) rc = TRUE; /* if no access hosts, say OK */          
  7077.      }                                                                          
  7078.      if (rc) break;                   /* if access OK, finished     */          
  7079.                                                                                 
  7080.      /* If access is not permitted, we keep checking because                    
  7081.       * there may be more than one entry in the access table                    
  7082.       * for this file, so that many host names can be given.                    
  7083.       */                                                                        
  7084.                                                                                 
  7085.    }                                                                            
  7086.  }                                                                              
  7087.                                                                                 
  7088.  (void)fclose(afp);                                                             
  7089.                                                                                 
  7090.  if (!rc) {                                                                     
  7091.    fprintf(stderr,"Not authorized from %s: '%s'\n",                             
  7092.                   R->hosttest, filetest);                                       
  7093.  }                                                                              
  7094.                                                                                 
  7095.  fflush(stderr);                                                                
  7096.                                                                                 
  7097.  return rc;                                                                     
  7098. }                                                                               
  7099.                                                                                 
  7100. /*=================================================================*/           
  7101.                                                                                 
  7102. /*******************************************************************/           
  7103. /*            This routine determines what type of gopher file     */           
  7104. /*            we've opened.  We'll return the file type to the     */           
  7105. /*            caller.                                              */           
  7106. /*                                                                 */           
  7107. /*            INPUT:   ident   pointer to first line of file       */           
  7108. /*                                                                 */           
  7109. /*            OUTPUT:   MENU   file type is a menu                 */           
  7110. /*                      FILE   file type is a file                 */           
  7111. /*                      INDEX  file type is an INDEX (not done)    */           
  7112. /*******************************************************************/           
  7113.                                                                                 
  7114. static char                                                                     
  7115. getftype(char *ident)                                                           
  7116. {                                                                               
  7117.  int   x;                              /* loop counter */                       
  7118.  char  buffer[RBUFSIZE];                                                        
  7119.  char *bufptr;                                                                  
  7120.                                                                                 
  7121.  /**********/                                                                   
  7122.  /*   first, convert the string to upper case...   */                           
  7123.  /*********/                                                                    
  7124.  strcpy(buffer,ident);                                                          
  7125.  bufptr = uppercase_and_trim_leading_space(buffer);                             
  7126.                                                                                 
  7127.  /**********/                                                                   
  7128.  /*   return the type of file.                     */                           
  7129.  /*********/                                                                    
  7130.                                                                                 
  7131.  if(strcmp(bufptr,MENUIDENT)==0) return(MENU);                                  
  7132.  if(strcmp(bufptr,INDEXIDENT)==0) return(INDEX);                                
  7133.                                                                                 
  7134.  /**********/                                                                   
  7135.  /*   don't know, so assume it's a "file" file...    */                         
  7136.  /*********/                                                                    
  7137.                                                                                 
  7138.  return(GFILE);                                                                 
  7139.                                                                                 
  7140. }                                                                               
  7141.                                                                                 
  7142. /*=================================================================*/           
  7143.                                                                                 
  7144. /*******************************************************************/           
  7145. /*            This routine figures out what type of parm line      */           
  7146. /*            the current line is.  We'll return the token         */           
  7147. /*            type to the caller.                                  */           
  7148. /*                                                                 */           
  7149. /*            INPUT:   buffer  pointer to first line of file       */           
  7150. /*                       (Note: string must be null terminated!    */           
  7151. /*            OUTPUT:   Type of token.  (See in include file...)   */           
  7152. /*******************************************************************/           
  7153.                                                                                 
  7154. static int                                                                      
  7155. menukeywd(char  *buffer,                                                        
  7156.           char  *token,                                                         
  7157.           char  *operand)                                                       
  7158. {                                                                               
  7159.  int             x;                              /* loop counter */             
  7160.  char           *tokval;                                                        
  7161.  char           *oprval;                                                        
  7162.  char           *tokptr;                                                        
  7163.  char            tokstr[256];                                                   
  7164.                                                                                 
  7165.  strcpy(tokstr,buffer);                                                         
  7166.  tokval=strtok(tokstr,"=");                                                     
  7167.  oprval=strtok(NULL,"");                                                        
  7168.  strcpy(token,tokval);                                                          
  7169.  strcpy(operand,oprval);                                                        
  7170.  tokptr = uppercase_and_trim_leading_space(token);                              
  7171.                                                                                 
  7172.  /*********/                                                                    
  7173.  /*  now look at the tokens to see if we have a weener... */                    
  7174.  /*********/                                                                    
  7175.                                                                                 
  7176.  if(strcmp(tokptr,TOKTYPE)==0) return(TYPETOK);                                 
  7177.  if(strcmp(tokptr,TOKNAME)==0) return(NAMETOK);                                 
  7178.  if(strcmp(tokptr,TOKPATH)==0) return(PATHTOK);                                 
  7179.  if(strcmp(tokptr,TOKHOST)==0) return(HOSTTOK);                                 
  7180.  if(strcmp(tokptr,TOKPORT)==0) return(PORTTOK);                                 
  7181.  if(strcmp(tokptr,TOKEND)==0) return(ENDTOK);                                   
  7182.                                                                                 
  7183.  /* for back compatibility with the old MVS GOPHER server */                    
  7184.                                                                                 
  7185.  if(strcmp(tokptr,TOKDISPLAY)==0) return(DISPLAYTOK);                           
  7186.  if(strcmp(tokptr,TOKSELECT)==0) return(SELECTTOK);                             
  7187.                                                                                 
  7188.  return(COMMENTTOK);                                                            
  7189.                                                                                 
  7190. }                                                                               
  7191.                                                                                 
  7192. /*=================================================================*/           
  7193.                                                                                 
  7194. /*******************************************************************/           
  7195. /*       This routine reads a line from the specified file.        */           
  7196. /*       if a read error occurs, an error message is printed and   */           
  7197. /*       FALSE is returned.                                        */           
  7198. /*                                                                 */           
  7199. /*       INPUT   buffer      pointer to buffer to place line       */           
  7200. /*               readfile    file structure to read from           */           
  7201. /*                                                                 */           
  7202. /*       OUTPUT  buffer      line that was read from the file      */           
  7203. /*               TRUE        read worked ok                        */           
  7204. /*               FALSE       read failed!                          */           
  7205. /*******************************************************************/           
  7206.                                                                                 
  7207. static Bool                                                                     
  7208. readaline(struct recvstruct *R)                                                 
  7209. {                                                                               
  7210.                                                                                 
  7211.  memset(R->buffer,0,RBUFSIZE);                                                  
  7212.  fread(R->buffer,RBUFSIZE,1,R->readfile);                                       
  7213.  if (ferror(R->readfile)) {                                                     
  7214.    /* perror("FREAD"); */                                                       
  7215.    fprintf(stderr,"GGSTASK: Error reading file\n");                             
  7216.    return(FALSE);                                                               
  7217.  }                                                                              
  7218.  trim_trailing_space(R->buffer); /* Remove trailing whitespace */               
  7219.  return(TRUE);                                                                  
  7220. }                                                                               
  7221.                                                                                 
  7222. /*=================================================================*/           
  7223.                                                                                 
  7224. /*******************************************************************/           
  7225. /*   This routine sends a file to the calling client.              */           
  7226. /*   It assumes the file is a text formatted file.                 */           
  7227. /*   INPUT:   buffer    pointer to the already read line...        */           
  7228. /*            readfile  file we're going to read from..            */           
  7229. /*            maxlen    size of the buffer.                        */           
  7230. /*            sockfd    socket descriptor for client.              */           
  7231. /*                                                                 */           
  7232. /*   OUTPUT:   send the file to the client                         */           
  7233. /*******************************************************************/           
  7234. static void                                                                     
  7235. sendafile(struct recvstruct *R)                                                 
  7236. {                                                                               
  7237.  int            x;                                                              
  7238.  char          *moveit;                                                         
  7239.                                                                                 
  7240.  /*******/                                                                      
  7241.  /*   send the first line (cause we already read it) */                         
  7242.  /*******/                                                                      
  7243.                                                                                 
  7244.  if (!GGMouts(R,R->buffer)) return;                                             
  7245.                                                                                 
  7246.  /*******/                                                                      
  7247.  /*   get the rest of the lines of the file and send them... */                 
  7248.  /*******/                                                                      
  7249.                                                                                 
  7250.  for (;;) {                                                                     
  7251.    if (!readaline(R)) {                                                         
  7252.      (void)GGMouts(R,"<<<*** I/O ERROR ON MVS FILE ***>>>");                    
  7253.      return;                                                                    
  7254.    }                                                                            
  7255.    if (feof(R->readfile)) break;                                                
  7256.    if (!GGMouts(R,R->buffer)) return;                                           
  7257.  }                                                                              
  7258. }                                                                               
  7259.                                                                                 
  7260. /*=================================================================*/           
  7261.                                                                                 
  7262. /*******************************************************************/           
  7263. /*   This routine formats a menu file into gopher data & sends it  */           
  7264. /*   to the client.                                                */           
  7265. /*   INPUT:   buffer    pointer to the already read line...        */           
  7266. /*            readfile  file we're going to read from..            */           
  7267. /*            maxlen    size of the buffer.                        */           
  7268. /*            sockfd    socket descriptor for client               */           
  7269. /*                                                                 */           
  7270. /*   OUTPUT:   send the menu to the client                         */           
  7271. /*******************************************************************/           
  7272.                                                                                 
  7273. #define MENU_STUFF_SIZE GOPHER_DESC_LENGTH + \                                  
  7274.                         GOPHER_PATH_LENGTH + \                                  
  7275.                         GOPHER_HOST_LENGTH + 20                                 
  7276.                                                                                 
  7277. static void                                                                     
  7278. sendamenu(struct recvstruct *R)                                                 
  7279. {                                                                               
  7280.  char           *moveit;                                                        
  7281.  char           *operptr;                                                       
  7282.  char           *typeoftype;             /*pointer for strtok   */              
  7283.  char           *cp;                                                            
  7284.  int             kindotoken;                                                    
  7285.  int             x;                         /* loop counter */                  
  7286.  char            token   [133];                                                 
  7287.  char            operand [133];                                                 
  7288.  char            outbuf  [MENU_STUFF_SIZE];                                     
  7289.  struct menuitem menu;                                                          
  7290.                                                                                 
  7291.  memset(&menu,0,sizeof menu );                                                  
  7292.  for (;;) {                                                                     
  7293.    if (!readaline(R)) break;                                                    
  7294.    if (feof(R->readfile)) break;                                                
  7295.    if (!*R->buffer) continue;                                                   
  7296.    kindotoken = menukeywd(R->buffer,token,operand);                             
  7297.    switch(kindotoken) {                                                         
  7298.      case TYPETOK:                                                              
  7299.           operptr = uppercase_and_trim_leading_space(operand);                  
  7300.           typeoftype = strtok(operptr," ");                                     
  7301.           if (strlen(typeoftype) == 1)      menu.type = *typeoftype;            
  7302.           else                                                                  
  7303.           if (EQUAL(typeoftype,TYPEFILE))   menu.type = GFILE;                  
  7304.           else                                                                  
  7305.           if (EQUAL(typeoftype,TYPEMENU))   menu.type = MENU;                   
  7306.           else                                                                  
  7307.           if (EQUAL(typeoftype,TYPEINDEX))  menu.type = INDEX;                  
  7308.           else                                                                  
  7309.           if (EQUAL(typeoftype,TYPETELNET)) menu.type = TELNET;                 
  7310.           else                                                                  
  7311.           if (EQUAL(typeoftype,TYPETN3270)) menu.type = TN3270;                 
  7312.           else                                                                  
  7313.           if (EQUAL(typeoftype,TYPEWHOIS))  menu.type = WHOIS;                  
  7314.           else                              menu.type = ERROR;                  
  7315.           break;                                                                
  7316.      case NAMETOK:                                                              
  7317.      case DISPLAYTOK:                                                           
  7318.           strncpy(menu.desc,     operptr, sizeof(menu.desc));                   
  7319.           break;                                                                
  7320.      case PATHTOK:                                                              
  7321.      case SELECTTOK:                                                            
  7322.           strncpy(menu.select,   operptr, sizeof(menu.select));                 
  7323.           break;                                                                
  7324.      case HOSTTOK:                                                              
  7325.           if (EQUAL(operptr,IDENT_HOST_FROB)) {  /* HOST=+  */                  
  7326.             if (insure_my_name(R)) {                                            
  7327.               strncpy(menu.hostname, R->myname, sizeof(menu.hostname));         
  7328.             }                                                                   
  7329.           }                                                                     
  7330.           else {                                                                
  7331.             strncpy(menu.hostname, operptr, sizeof(menu.hostname));             
  7332.           }                                                                     
  7333.           break;                                                                
  7334.      case PORTTOK:                                                              
  7335.           if (EQUAL(operptr,IDENT_HOST_FROB)) {  /* PORT=+  */                  
  7336.             menu.port = R->myport;                                              
  7337.           }                                                                     
  7338.           else {                                                                
  7339.             menu.port=atoi(operptr);                                            
  7340.           }                                                                     
  7341.           break;                                                                
  7342.      case ENDTOK:                                                               
  7343.           if (menu.port == 0) {                                                 
  7344.             switch (menu.type) {                                                
  7345.               case TELNET: break;                                               
  7346.               case TN3270: break;                                               
  7347.               default:     menu.port = GOPHER_PORT_NUMBER; break;               
  7348.             }                                                                   
  7349.           }                                                                     
  7350.           /* If host is local and path is in the form "(member)",               
  7351.            * and current dsname is a PDS, then use same PDS:                    
  7352.            * i.e. turn PATH=(FOOBAR) into PATH=AA.BB.CC(FOOBAR)                 
  7353.            */                                                                   
  7354.           if (*R->myname                                                        
  7355.            && EQUAL(menu.hostname,R->myname)                                    
  7356.            && *menu.select == '('        /* ) */                                
  7357.            && (cp = strchr(R->dsname,'(' /* ) */ ))) {                          
  7358.             memcpy(outbuf, R->dsname, (cp-R->dsname));                          
  7359.             strcpy(outbuf+(cp-R->dsname), menu.select);                         
  7360.             strncpy(menu.select, outbuf, sizeof(menu.select));                  
  7361.           }                                                                     
  7362.           if (*menu.desc && *menu.hostname) {                                   
  7363.             sprintf(outbuf,"%c%s\t%s\t%s\t%d",                                  
  7364.                            menu.type,menu.desc,                                 
  7365.                            menu.select,menu.hostname,menu.port);                
  7366.             if (!GGMouts(R,outbuf)) return;                                     
  7367.           }                                                                     
  7368.           fflush(stdout);                                                       
  7369.           memset(&menu,0,sizeof menu );                                         
  7370.           break;                                                                
  7371.      default:                                                                   
  7372.           break;                                                                
  7373.        }                                                                        
  7374.    }                                                                            
  7375. }                                                                               
  7376.                                                                                 
  7377. /*=================================================================*/           
  7378.                                                                                 
  7379. static Bool                                                                     
  7380. get_directory(struct recvstruct *R)                                             
  7381. {                                                                               
  7382.  FILE              *dirfile;                                                    
  7383.  int                i;                                                          
  7384.  short              block_count;                                                
  7385.  short              bump_amount;                                                
  7386.  Bool               reject;                                                     
  7387.  Bool               no_more;                                                    
  7388.  char              *cp;                                                         
  7389.  char              *mp;                                                         
  7390.  char               dirblk  [256];                                              
  7391.  char               pdsspec [256];                                              
  7392.  char               entry   [256];                                              
  7393.                                                                                 
  7394.  /* The local path name is required for this function. */                       
  7395.                                                                                 
  7396.  if (!insure_my_name(R)) return FALSE;                                          
  7397.                                                                                 
  7398.  if ((dirfile=fopen(R->buffer,"rb,recfm=u,lrecl=256")) == NULL) {               
  7399.    perror(R->buffer);                                                           
  7400.    printf("Can't open PDS directory:%s\n",R->dsname);                           
  7401.    gbarf(R,"the GOPHER server can't open the directory");                       
  7402.    return(FALSE);                                                               
  7403.  }                                                                              
  7404.                                                                                 
  7405.  while (!feof(dirfile)) {                                                       
  7406.                                                                                 
  7407.    no_more = FALSE;                                                             
  7408.                                                                                 
  7409.    do {                                                                         
  7410.      memset(dirblk,0x00,256);                                                   
  7411.      fread(dirblk,256,1,dirfile);                                               
  7412.      if (feof(dirfile)) break;                                                  
  7413.      if (ferror(dirfile)) {                                                     
  7414.        printf("Can't read PDS directory:%s\n", R->fileptr);                     
  7415.        gbarf(R,"the GOPHER server can't read the directory");                   
  7416.        fclose(dirfile);                                                         
  7417.        return FALSE;                                                            
  7418.      }                                                                          
  7419.      mp = dirblk;                                                               
  7420.      block_count = *(short *)mp - 2;   /* # bytes in dir block */               
  7421.      mp += 2;                        /* addr of dir block data */               
  7422.      while (block_count > 0) {                                                  
  7423.        if (memcmp(mp,"\xff\xff\xff\xff\xff\xff\xff\xff",8)==0) break;           
  7424.        reject = FALSE;                                                          
  7425.        /*                                                                       
  7426.         * Uncomment this if you want to skip aliases.                           
  7427.         * It is recommended that you let aliases through, since                 
  7428.         * they often have better names (e.g. TSO HELP files)                    
  7429.         *                                                                       
  7430.         * if ((mp[11] & 0x80) != 0) {                                           
  7431.         *   fprintf(stderr,"Skipping alias:  %-8.8s\n",mp);                     
  7432.         *   reject = TRUE;                                                      
  7433.         * }                                                                     
  7434.         */                                                                      
  7435.        if (!reject) {                                                           
  7436.          strcpy(pdsspec, R->dsname);                                            
  7437.          cp = strchr(pdsspec, '\0');                                            
  7438.          *(cp++) = '(';                                                         
  7439.          for (i = 0; i < 8 && mp[i] != ' '; cp++, i++) *cp = mp[i];             
  7440.          *(cp++) = ')';                                                         
  7441.          *cp = '\0';                                                            
  7442.          sprintf(entry,"0%8.8s\t%s\t%s\t%d",                                    
  7443.                        mp, pdsspec, R->myname, SERV_TCP_PORT);                  
  7444.          (void)GGMouts(R,entry);                                                
  7445.        }                                                                        
  7446.        bump_amount = 12 + ((mp[11] & 0x1f) * 2);                                
  7447.        mp += bump_amount;                                                       
  7448.        block_count -= bump_amount;                                              
  7449.      }                                                                          
  7450.    } while(!no_more);                                                           
  7451.                                                                                 
  7452.  }                                                                              
  7453.                                                                                 
  7454.  fclose(dirfile);                                                               
  7455.  return TRUE;                                                                   
  7456. }                                                                               
  7457.                                                                                 
  7458. /*=================================================================*/           
  7459.                                                                                 
  7460. static Bool                                                                     
  7461. get_flat_file(struct recvstruct *R)                                             
  7462. {                                                                               
  7463.  int                x;            /* loop counter*/                             
  7464.  int                numread;      /* number of items read... */                 
  7465.  char               filetype;     /* type of file we're dealing with*/          
  7466.                                                                                 
  7467.  if ((R->readfile=fopen(R->buffer,"rb,type=record")) == NULL) {                 
  7468.    perror(R->buffer);                                                           
  7469.    printf("INVALID! requested:%s\n",R->fileptr);                                
  7470.    gbarf(R,"the GOPHER server couldn't open the file");                         
  7471.    return(FALSE);                                                               
  7472.  }                                                                              
  7473.                                                                                 
  7474.  /************/                                                                 
  7475.  /*  get the first line and see what type of file we've got.      */            
  7476.  /************/                                                                 
  7477.                                                                                 
  7478.  if (readaline(R) && !feof(R->readfile)) {                                      
  7479.                                                                                 
  7480.    filetype=getftype(R->buffer);                                                
  7481.                                                                                 
  7482.   /************/                                                                
  7483.   /*  Now let's go do whatever we need to for this file type.    */             
  7484.   /************/                                                                
  7485.                                                                                 
  7486.    switch(filetype) {                                                           
  7487.      case MENU:                                                                 
  7488.                  sendamenu(R);                                                  
  7489.                  break;                                                         
  7490.      case GFILE:                                                                
  7491.      default:                                                                   
  7492.                  sendafile(R);                                                  
  7493.                  break;                                                         
  7494.    }                                                                            
  7495.                                                                                 
  7496.  }                                                                              
  7497.                                                                                 
  7498.  if(fclose(R->readfile) < 0) {                                                  
  7499.    /* perror("PROCESS CLOSE"); */                                               
  7500.    fprintf(stderr,"GGSTASK: Error closing file %s\n",R->fileptr);               
  7501.    gbarf(R,"the GOPHER server couldn't close the file");                        
  7502.    return FALSE;                                                                
  7503.  }                                                                              
  7504.                                                                                 
  7505.  return TRUE;                                                                   
  7506.                                                                                 
  7507. }                                                                               
  7508.                                                                                 
  7509. /*=================================================================*/           
  7510.                                                                                 
  7511. #define PARAMETER   unsigned int                                                
  7512. #define LASTPARM(X) ((unsigned int)(X) | 0x80000000)                            
  7513.                                                                                 
  7514.                                                                                 
  7515. static Bool                                                                     
  7516. get_exec_data(struct recvstruct *R)                                             
  7517. {                                                                               
  7518.  char              *command;                                                    
  7519.  char              *commandargs;                                                
  7520.  unsigned int       bitflags;                                                   
  7521.  int                rexxrc;                                                     
  7522.  int                irxexecrc;                                                  
  7523.  int                commandlength;                                              
  7524.  int                scan_count;                                                 
  7525.  int                i;                                                          
  7526.  Bool               rc;                                                         
  7527.  int              (*irxexec)();                                                 
  7528.  FILE              *fp;                                                         
  7529.  char               exectest[RBUFSIZE];                                         
  7530.  PARAMETER          parameter[11];                                              
  7531.  struct {                                                                       
  7532.                          /* repeat this block for each argument */              
  7533.          char      *argstring_ptr;                                              
  7534.          int        argstring_length;                                           
  7535.                          /* end repeat this block for each argument */          
  7536.          int        argstring_end;                                              
  7537.         }           arguments;                                                  
  7538.                                                                                 
  7539.  struct {                                                                       
  7540.          char       acryn[8];       /* "IRXEXECB" */                            
  7541.          int        length;                                                     
  7542.          int        reserved1;                                                  
  7543.          char       member[8];                                                  
  7544.          char       ddname[8];                                                  
  7545.          char       subcom[8];                                                  
  7546.          char      *dsnptr;                                                     
  7547.          int        dsnlen;                                                     
  7548.         }           execblk;                                                    
  7549.                                                                                 
  7550.   /*                                                                            
  7551.    * Menu item should look like this:                                           
  7552.    *                                                                            
  7553.    * exec:rexxname any args                                                     
  7554.    *                                                                            
  7555.    * The exec should write output to SYSTSPRT.  Normal TSO command              
  7556.    * output will be captured by the SYSTSPRT allocation only if                 
  7557.    * the Gopher server is run as a batch job.                                   
  7558.    *                                                                            
  7559.    * If this was sent by the client with a type 7 or type w, then               
  7560.    * additional args will appear at the end delimited by a space.               
  7561.    */                                                                           
  7562.                                                                                 
  7563.  irxexec = NULL;                                                                
  7564.  rc = TRUE;                                                                     
  7565.  scan_count = 0;                                                                
  7566.                                                                                 
  7567.  if (R->wargptr) {                                                              
  7568.    commandlength = strlen(R->fileptr) + strlen(R->wargptr) + 4;                 
  7569.    command = (char *)malloc(commandlength);                                     
  7570.    if (!command) {                                                              
  7571.      printf("Cannot allocate %d bytes of memory for exec\n",                    
  7572.             commandlength);                                                     
  7573.      gbarf(R,"the GOPHER server ran out of memory");                            
  7574.      return FALSE;                                                              
  7575.    }                                                                            
  7576.    else sprintf(command,"%s %s",R->fileptr,R->wargptr);                         
  7577.  }                                                                              
  7578.  else {                                                                         
  7579.    commandlength = 0;                                                           
  7580.    command = R->fileptr;                                                        
  7581.  }                                                                              
  7582.                                                                                 
  7583.  *exectest = '\0';                                                              
  7584.  sscanf(command, "%s %n", exectest, &scan_count);                               
  7585.  if (strlen(exectest) > 8) {                                                    
  7586.    gbarf(R,"name of exec is too long");                                         
  7587.    return FALSE;                                                                
  7588.  }                                                                              
  7589.  commandargs = command + scan_count;                                            
  7590.                                                                                 
  7591.  if (rc) {                                                                      
  7592.    irxexec = (int(*)())fetch("IRXEXEC");                                        
  7593.    if (!irxexec) {                                                              
  7594.      printf("Cannot fetch IRXEXEC\n");                                          
  7595.      rc = FALSE;                                                                
  7596.    }                                                                            
  7597.  }                                                                              
  7598.                                                                                 
  7599.  /* Give the exec an empty SYSTSPRT file to write into.                         
  7600.   * Then when we read it we can see only what was added.                        
  7601.   * Since IRXEXEC doesn't close SYSTSPRT, we can't remove it                    
  7602.   * and reallocate it.                                                          
  7603.   */                                                                            
  7604.                                                                                 
  7605.  if (rc) {                                                                      
  7606.    fp = fopen("DD:SYSTSPRT","w");                                               
  7607.    if (!fp) {                                                                   
  7608.      perror("DD:SYSTSPRT");                                                     
  7609.      printf("Cannot open SYSTSPRT to prepare for REXX exec\n");                 
  7610.      rc = FALSE;                                                                
  7611.    }                                                                            
  7612.                                                                                 
  7613.    /* Open for write + close = clear it out */                                  
  7614.                                                                                 
  7615.    else if (fclose(fp) < 0) {                                                   
  7616.      printf("Cannot close SYSTSPRT to prepare for REXX exec\n");                
  7617.      rc = FALSE;                                                                
  7618.    }                                                                            
  7619.  }                                                                              
  7620.                                                                                 
  7621.  /* Set up parameters for IRXEXEC:                                              
  7622.   *                                                                             
  7623.   * Param 1  -  address of EXECBLK                                              
  7624.   * Param 2  -  address of arguments                                            
  7625.   * Param 3  -  bitflags                                                        
  7626.   * Param 4  -  address of INSTBLK                                              
  7627.   * Param 5  -  address of CPPL                                                 
  7628.   * Param 6  -  address of EVALBLOCK                                            
  7629.   * Param 7  -  address of 8-byte work area                                     
  7630.   * Param 8  -  address of user field                                           
  7631.   * Param 9  -  address of environment block                                    
  7632.   * Param 10 -  return code                                                     
  7633.   *                                                                             
  7634.   */                                                                            
  7635.                                                                                 
  7636.  if (rc) {                                                                      
  7637.                                                                                 
  7638.    /* set up exec block */                                                      
  7639.                                                                                 
  7640.    memset (&execblk, 0, sizeof(execblk));                                       
  7641.    execblk.length = sizeof(execblk);                                            
  7642.    memcpy (execblk.acryn, "IRXEXECB", 8);                                       
  7643.    strncpy(execblk.member,exectest,8);                                          
  7644.    for (i=0;i<8;i++) {                                                          
  7645.      if (execblk.member[i] == '\0')                                             
  7646.          execblk.member[i] = ' ';                                               
  7647.    }                                                                            
  7648.    /* We may have just clobbered this, so do this after... */                   
  7649.                                                                                 
  7650.    memcpy (execblk.ddname, REXX_EXEC_LIBRARY_DDNAME, 8);                        
  7651.    memcpy (execblk.subcom, REXX_EXEC_SUBCOM,     8);                            
  7652.                                                                                 
  7653.    /* set up arguments  */                                                      
  7654.                                                                                 
  7655.    arguments.argstring_ptr    = commandargs;                                    
  7656.    arguments.argstring_length = strlen(commandargs);                            
  7657.    arguments.argstring_end    = 0xffffffff;                                     
  7658.                                                                                 
  7659.    /* Invoke the rexx exec */                                                   
  7660.                                                                                 
  7661.    if (!R->outfp) printf("Executing:%s\n", command);                            
  7662.                                                                                 
  7663. #define INVOKE_EXEC_AS_COMMAND            (unsigned int)0x80000000              
  7664. #define INVOKE_EXEC_AS_EXTERNAL_FUNCTION  (unsigned int)0x40000000              
  7665. #define INVOKE_EXEC_AS_SUBROUTINE         (unsigned int)0x20000000              
  7666. #define RETURN_EXTENDED_RETURN_CODES      (unsigned int)0x10000000              
  7667.                                                                                 
  7668.    rexxrc = 0;                                                                  
  7669.    bitflags = (unsigned int)(INVOKE_EXEC_AS_COMMAND +                           
  7670.                              RETURN_EXTENDED_RETURN_CODES);                     
  7671.                                                                                 
  7672.    parameter[ 1] =   (PARAMETER)&execblk;                                       
  7673.    parameter[ 2] =   (PARAMETER)&arguments;                                     
  7674.    parameter[ 3] =   (PARAMETER)bitflags;                                       
  7675.    parameter[ 4] =   (PARAMETER)NULL;  /* no INSTBLK */                         
  7676.    parameter[ 5] =   (PARAMETER)NULL;  /* no CPPL    */                         
  7677.    parameter[ 6] =   (PARAMETER)NULL;  /* no eval block */                      
  7678.    parameter[ 7] =   (PARAMETER)NULL;  /* no work area */                       
  7679.    parameter[ 8] =   (PARAMETER)NULL;  /* no user field, last parm */           
  7680.    parameter[ 9] =   (PARAMETER)NULL;  /* no environment block */               
  7681.    parameter[10] =   (PARAMETER)0;     /* return code */                        
  7682.                                                                                 
  7683.    irxexecrc = (*irxexec) (                                                     
  7684.                            ¶meter[1],                                       
  7685.                            ¶meter[2],                                       
  7686.                            ¶meter[3],                                       
  7687.                            ¶meter[4],                                       
  7688.                            ¶meter[5],                                       
  7689.                            ¶meter[6],                                       
  7690.                            ¶meter[7],                                       
  7691.                            LASTPARM(¶meter[8]), /* old REXX */              
  7692.                            ¶meter[9],                                       
  7693.                            LASTPARM(¶meter[10]) /* new REXX */              
  7694.                           );                                                    
  7695.                                                                                 
  7696.    if (irxexecrc != 0) {                                                        
  7697.      fprintf(stderr,"Return code from IRXEXEC is %d\n", irxexecrc);             
  7698.      gbarf(R,"the Gopher server was unable to run the exec");                   
  7699.      rc = FALSE;                                                                
  7700.    }                                                                            
  7701.    else {                                                                       
  7702.                                                                                 
  7703.      rexxrc = parameter[10];                                                    
  7704.                                                                                 
  7705.      if (!R->outfp) printf("Return code from exec is %d\n", rexxrc);            
  7706.                                                                                 
  7707.      /* Read what the exec wrote. */                                            
  7708.                                                                                 
  7709.      strcpy(R->buffer,"DD:SYSTSPRT");                                           
  7710.      R->fileptr = R->buffer;                                                    
  7711.      rc = get_flat_file(R);                                                     
  7712.                                                                                 
  7713.    }                                                                            
  7714.                                                                                 
  7715.  }                                                                              
  7716.                                                                                 
  7717.  else {                                                                         
  7718.      gbarf(R,"the GOPHER server had a problem with the exec");                  
  7719.  }                                                                              
  7720.                                                                                 
  7721.  if (irxexec) release((void (*)())irxexec);                                     
  7722.                                                                                 
  7723.  if (commandlength > 0) free(command);                                          
  7724.                                                                                 
  7725.  return rc;                                                                     
  7726.                                                                                 
  7727. }                                                                               
  7728.                                                                                 
  7729. /*=================================================================*/           
  7730.                                                                                 
  7731. /*******************************************************************/           
  7732. /*   This routine Processes the file the user requested.           */           
  7733. /*   If it's a menu, we'll form a menu line, if it's a             */           
  7734. /*   file, we'll just send it as is.                               */           
  7735. /*                                                                 */           
  7736. /*   INPUT:   filename  pointer to the file name to open           */           
  7737. /*            sockfd    socket descriptor for the client           */           
  7738. /*                                                                 */           
  7739. /*   OUTPUT:   print "gopher" lines.                               */           
  7740. /*             TRUE  - file printed ok.                            */           
  7741. /*             FALSE - Error reading or writing                    */           
  7742. /*******************************************************************/           
  7743.                                                                                 
  7744. Bool                                                                            
  7745. GGMproc(struct recvstruct *R)                                                   
  7746. {                                                                               
  7747.  int                x;            /* loop counter*/                             
  7748.  int                numread;      /* number of items read... */                 
  7749.  int                hacksize;     /* length of hack prefix before : */          
  7750.  Bool               rc;           /* return value */                            
  7751.  enum data_set_type dstype;       /* SEQ, PDS or UNK */                         
  7752.  char              *p;                                                          
  7753.  char              *q;                                                          
  7754.  char              *tabptr;                                                     
  7755.  char              *colonptr;                                                   
  7756.  char               ddname    [  9];                                            
  7757.  char               hackprefix[ 17];                                            
  7758.                                                                                 
  7759.  *ddname     = '\0';                                                            
  7760.  *hackprefix = '\0';                                                            
  7761.                                                                                 
  7762.  /************/                                                                 
  7763.  /*  First, strip off any "bad" characters from the arguments. */               
  7764.  /************/                                                                 
  7765.                                                                                 
  7766.  /*                                                                             
  7767.   * Break the argument up into one or two pieces delimited by tab.              
  7768.   */                                                                            
  7769.                                                                                 
  7770.  R->fileptr = R->buffer;        /* filename passed in buffer */                 
  7771.                                                                                 
  7772.  tabptr = strchr(R->fileptr,'\t');                                              
  7773.  if (tabptr) {                                                                  
  7774.    *tabptr = '\0';                                                              
  7775.    R->fileptr = trim_leading_and_trailing_space(R->fileptr);                    
  7776.    R->wargptr = trim_leading_and_trailing_space(tabptr+1);                      
  7777.  }                                                                              
  7778.  else {                                                                         
  7779.    R->fileptr = trim_leading_and_trailing_space(R->fileptr);                    
  7780.    R->wargptr = NULL;                                                           
  7781.  }                                                                              
  7782.                                                                                 
  7783.  if (!*R->fileptr) {                                                            
  7784.    R->fileptr = DEFAULT_DIRECTORY;                                              
  7785.  }                                                                              
  7786.                                                                                 
  7787.  /* If first character is numeric, assume it's a gopher type.                   
  7788.   * Later we will actually support different types...                           
  7789.   */                                                                            
  7790.                                                                                 
  7791.  switch (*R->fileptr) {                                                         
  7792.    case '0':                                                                    
  7793.    case '1':                                                                    
  7794.    case '2':                                                                    
  7795.    case '3':                                                                    
  7796.    case '4':                                                                    
  7797.    case '5':                                                                    
  7798.    case '6':                                                                    
  7799.    case '7':                                                                    
  7800.    case '8':                                                                    
  7801.    case '9':  R->fileptr++; break;                                              
  7802.    default:                 break;                                              
  7803.  }                                                                              
  7804.                                                                                 
  7805.  if (!R->outfp) printf("%s: requested:%s;\n",R->hostname,R->fileptr);           
  7806.                                                                                 
  7807.  /*                                                                             
  7808.   * Process special hacks here.                                                 
  7809.   *                                                                             
  7810.   * For example, if the file name begins with "exec:", then                     
  7811.   * execute the specified REXX exec.                                            
  7812.   *                                                                             
  7813.   * Hackless names are processed as files.  "dd:" is not a                      
  7814.   * special hack but the normal C/370 DDname reference.                         
  7815.   *                                                                             
  7816.   */                                                                            
  7817.                                                                                 
  7818.  colonptr = strchr(R->fileptr,':');                                             
  7819.  if (colonptr) {                                                                
  7820.    hacksize = colonptr - R->fileptr;                                            
  7821.    if (hacksize > 0 && hacksize < sizeof(hackprefix)) {                         
  7822.      for (p = hackprefix, q = R->fileptr;                                       
  7823.           hacksize > 0;                                                         
  7824.           p++, q++, hacksize--) *p = toupper(*q);                               
  7825.      *p = '\0';                                                                 
  7826.    }                                                                            
  7827.  }                                                                              
  7828.                                                                                 
  7829.  if (EQUAL(hackprefix,"EXEC")) {                                                
  7830.   /*                                                                            
  7831.    * REXX exec, which must reside in SYSEXEC DD.                                
  7832.    */                                                                           
  7833.    if (!authorized_file(R)) {                                                   
  7834.      gbarf(R,"the GOPHER server won't run the exec for you");                   
  7835.      rc = FALSE;                                                                
  7836.    }                                                                            
  7837.    else {                                                                       
  7838.      R->fileptr = colonptr + 1;  /* point to exec itself */                     
  7839.      rc = get_exec_data(R);                                                     
  7840.    }                                                                            
  7841.  }                                                                              
  7842.  else                                                                           
  7843.  if (EQUAL(hackprefix,"DD")) {                                                  
  7844.   /*                                                                            
  7845.    * C/370 style ddname.  Assume sequential file - cannot be a PDS              
  7846.    * because I don't feel like trying to determine that right now.              
  7847.    */                                                                           
  7848.    if (!authorized_file(R)) {                                                   
  7849.      gbarf(R,"the GOPHER server won't read the DD for you");                    
  7850.      rc = FALSE;                                                                
  7851.    }                                                                            
  7852.    else {                                                                       
  7853.      strcpy(R->buffer,R->fileptr); /* still points to "DD:xxxxxxxx" */          
  7854.      dstype = SEQ;                                                              
  7855.      rc = get_flat_file(R);                                                     
  7856.    }                                                                            
  7857.  }                                                                              
  7858.  else {                                                                         
  7859.    /* Regular file name without ":" hack, or with invalid ":" hack.             
  7860.     * Check to see that the file name is on our "official" list.                
  7861.     */                                                                          
  7862.    if (!authorized_file(R)) {                                                   
  7863.      gbarf(R,"the GOPHER server won't let you see the file");                   
  7864.      rc = FALSE;                                                                
  7865.    }                                                                            
  7866.    else {                                                                       
  7867.                                                                                 
  7868.    /* Dynamically allocate data set and use generated ddname.                   
  7869.     * Note that we have to allocate the data set name to a ddname and           
  7870.     * then open the ddname to prevent C/370 from barfing on otherwise           
  7871.     * valid data set names like those with hyphens in them.  But this           
  7872.     * also lets us determine if the data set is sequential or a PDS.            
  7873.     */                                                                          
  7874.      strcpy(R->dsname,R->fileptr);                                              
  7875.      dstype = GGMalloc(R->dsname,ddname,UNK,0);                                 
  7876.      sprintf(R->buffer,"DD:%s",ddname);                                         
  7877.      switch (dstype) {                                                          
  7878.        case SEQ: rc = get_flat_file(R); break;                                  
  7879.        case PDS: rc = get_directory(R); break;                                  
  7880.        default:                                                                 
  7881.                printf("INVALID! requested:%s\n",R->fileptr);                    
  7882.                gbarf(R,"the GOPHER server couldn't allocate the file");         
  7883.                rc = FALSE;                                                      
  7884.      }                                                                          
  7885.    }                                                                            
  7886.  }                                                                              
  7887.                                                                                 
  7888.  GGMunalc(ddname);  /* free the ddname if set */                                
  7889.                                                                                 
  7890.  if (!rc) {                                                                     
  7891.    fflush(stdout);                                                              
  7892.    fflush(stderr);                                                              
  7893.  }                                                                              
  7894.                                                                                 
  7895.  return rc;                                                                     
  7896.                                                                                 
  7897. }                                                                               
  7898.                                                                                 
  7899. ./   ADD NAME=GGMSOCKT                                                          
  7900.                                                                                 
  7901.  /********************************************************************/         
  7902.  /*                                                                  */         
  7903.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7904.  /*                                                                  */         
  7905.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  7906.  /*                                                                  */         
  7907.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7908.  /* including the implied warranties of merchantability and fitness, */         
  7909.  /* are expressly denied.                                            */         
  7910.  /*                                                                  */         
  7911.  /* Provided this copyright notice is included, this software may    */         
  7912.  /* be freely distributed and not offered for sale.                  */         
  7913.  /*                                                                  */         
  7914.  /* Changes or modifications may be made and used only by the maker  */         
  7915.  /* of same, and not further distributed.  Such modifications should */         
  7916.  /* be mailed to the author for consideration for addition to the    */         
  7917.  /* software and incorporation in subsequent releases.               */         
  7918.  /*                                                                  */         
  7919.  /********************************************************************/         
  7920.                                                                                 
  7921. #pragma  csect(code,  "GG@SOCKT")                                               
  7922. #pragma  csect(static,"GG$SOCKT")                                               
  7923. #include "gg.h"                                                                 
  7924.                                                                                 
  7925. /****** Output one data line for the server. *************************/         
  7926.                                                                                 
  7927. Bool                                                                            
  7928. GGMsockt(gp,sp)                                                                 
  7929. Rstruc ggcb        *gp;                                                         
  7930. Rstruc connection  *sp;                                                         
  7931. {                                                                               
  7932.  int                gopher_bytes;                                               
  7933.  int                writrc;                                                     
  7934.  char              *s_buf;                                                      
  7935.  Bool               procok;                                                     
  7936.  struct recvstruct *R;                                                          
  7937.                                                                                 
  7938.  /* Before sending a request to the server, do a cleanup operation              
  7939.   * to make sure that no more responses are coming from the server.             
  7940.   */                                                                            
  7941.                                                                                 
  7942.  GGMesrvr(gp,sp);           /* End server read */                               
  7943.                                                                                 
  7944.  /* If local mode, call server subtask processor with command. */               
  7945.                                                                                 
  7946.  if ((R=gp->recvp)) {                                                           
  7947.    if (!R->outfp) {                                                             
  7948.      CRIT1("Can't send data locally, non-socket not connected");                
  7949.      return FALSE;                                                              
  7950.    }                                                                            
  7951.    strncpy(R->buffer, gp->gopher_command, sizeof(R->buffer)-1);                 
  7952.    strcpy(R->myname, LOCAL_HOST_FROB);  /* used by PDS feature */               
  7953.                                                                                 
  7954.    /* allocate SYSTSPRT file, used by REXX EXEC interface */                    
  7955.                                                                                 
  7956.    if (GGMtso(                                                                  
  7957.      "ALLOC FI(SYSTSPRT) T SP(100 100) REL REU DEL"                             
  7958.      " RECFM(V B) LRECL(1024) BLKSIZE(32760)"                                   
  7959.              ) != 0) {                                                          
  7960.      fprintf(stderr,                                                            
  7961.        "Warning: Cannot allocate temporary SYSTSPRT file.\n");                  
  7962.      fprintf(stderr,                                                            
  7963.        "         Some interfaces may not work properly.\n");                    
  7964.    }                                                                            
  7965.                                                                                 
  7966.    procok = GGMproc(R);                                                         
  7967.                                                                                 
  7968.    /* free SYSTSPRT file, used by REXX EXEC interface */                        
  7969.                                                                                 
  7970.    (void)GGMunalc("SYSTSPRT");                                                  
  7971.                                                                                 
  7972.    /* Prepare to read from the beginning of the file */                         
  7973.                                                                                 
  7974.    if (fseek(R->outfp, 0, SEEK_SET) != 0) {                                     
  7975.      CRIT1("Can't reposition to start of local file");                          
  7976.      return FALSE;                                                              
  7977.    }                                                                            
  7978.    return procok;                                                               
  7979.  }                                                                              
  7980.                                                                                 
  7981.  gopher_bytes = strlen(gp->gopher_command);                                     
  7982.                                                                                 
  7983.  memcpy(sp->client_buf,gp->gopher_command,gopher_bytes);                        
  7984.  sp->client_buf[gopher_bytes]   = CARRIAGE_RETURN;                              
  7985.  sp->client_buf[gopher_bytes+1] = LINE_FEED;                                    
  7986.                                                                                 
  7987.  if (sp->receiving_text &&                                                      
  7988.      gopher_bytes == 1  &&                                                      
  7989.      sp->client_buf[0] == '.') {                                                
  7990.    sp->receiving_text = FALSE;                                                  
  7991.  }                                                                              
  7992.                                                                                 
  7993.  if (gp->debug_mode)                                                            
  7994.     GGMdump(gp,"Writing to server",sp->client_buf,gopher_bytes+2);              
  7995.                                                                                 
  7996. #ifdef MVS                                                                      
  7997.  EBCDIC_TO_ASCII(sp->client_buf,gopher_bytes+2);                                
  7998. #endif                                                                          
  7999.                                                                                 
  8000.  writrc = write(sp->ns, sp->client_buf, gopher_bytes+2);                        
  8001.  if (writrc < 0) {                                                              
  8002.    sp->connection_broken = TRUE;                                                
  8003.    CRIT2("TCP/IP error: write() failed to send data to server %s.",             
  8004.          gp->ggserver);                                                         
  8005.    return FALSE;                                                                
  8006.  }                                                                              
  8007.                                                                                 
  8008.  /* Prepare server for read. */                                                 
  8009.                                                                                 
  8010.  sp->server_has_something_pending = TRUE;                                       
  8011.  sp->server_finished_replying     = FALSE;                                      
  8012.  sp->sending_text                 = FALSE;                                      
  8013.  sp->dont_read                    = FALSE;                                      
  8014.                                                                                 
  8015.  (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                      
  8016.  (void)GGMispf(gp,"DISPLAY PANEL(GGMLSOCK)");                                   
  8017.                                                                                 
  8018.  return TRUE;                                                                   
  8019. }                                                                               
  8020.                                                                                 
  8021. ./   ADD NAME=GGMSOPT,SSI=01000006                                              
  8022.                                                                                 
  8023.  /********************************************************************/         
  8024.  /*                                                                  */         
  8025.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8026.  /*                                                                  */         
  8027.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8028.  /*                                                                  */         
  8029.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8030.  /* including the implied warranties of merchantability and fitness, */         
  8031.  /* are expressly denied.                                            */         
  8032.  /*                                                                  */         
  8033.  /* Provided this copyright notice is included, this software may    */         
  8034.  /* be freely distributed and not offered for sale.                  */         
  8035.  /*                                                                  */         
  8036.  /* Changes or modifications may be made and used only by the maker  */         
  8037.  /* of same, and not further distributed.  Such modifications should */         
  8038.  /* be mailed to the author for consideration for addition to the    */         
  8039.  /* software and incorporation in subsequent releases.               */         
  8040.  /*                                                                  */         
  8041.  /********************************************************************/         
  8042.                                                                                 
  8043. #pragma  csect(code,  "GG@SOPT ")                                               
  8044. #pragma  csect(static,"GG$SOPT ")                                               
  8045. #include "gg.h"                                                                 
  8046.                                                                                 
  8047. #define BOOLOPTSET(A,B,C) \                                                     
  8048.    switch (A[0]) { \                                                            
  8049.      case  'n': \                                                               
  8050.      case  'N':   B = FALSE; break; \                                           
  8051.      case  'y': \                                                               
  8052.      case  'Y':   B = TRUE; break; \                                            
  8053.      case '\0': \                                                               
  8054.      default:     B = C; break; \                                               
  8055.    }                                                                            
  8056.                                                                                 
  8057. /****** Set options that are stored in ISPF profile. *****************/         
  8058.                                                                                 
  8059. void                                                                            
  8060. GGMsopt(gp,which)                                                               
  8061. Rstruc ggcb        *gp;                                                         
  8062. enum user_option    which;                                                      
  8063. {                                                                               
  8064.  int                arrows;                                                     
  8065.  char               ggextpow[  4];                                              
  8066.  char               ggextpap[  4];                                              
  8067.  char               ggscroll[  4];                                              
  8068.  char               ggcursor[  4];                                              
  8069.                                                                                 
  8070.  if (which == OPTION_ALL) {                                                     
  8071.    GGMispf(gp, "VGET (GGEXTPOW GGEXTPAP GGSCROLL GGCURSOR) PROFILE");           
  8072.  }                                                                              
  8073.                                                                                 
  8074.  if (which == OPTION_ALL || which == OPTION_OTHER) {                            
  8075.                                                                                 
  8076.    (void)GGMivget(gp,"GGEXTPOW ", ggextpow, sizeof(ggextpow));                  
  8077.    (void)GGMivget(gp,"GGEXTPAP ", ggextpap, sizeof(ggextpap));                  
  8078.                                                                                 
  8079.    BOOLOPTSET(ggextpow, gp->warn_overwrite,              TRUE);                 
  8080.    BOOLOPTSET(ggextpap, gp->warn_append,                 TRUE);                 
  8081.                                                                                 
  8082.  }                                                                              
  8083.                                                                                 
  8084.  if (which == OPTION_ALL || which == OPTION_VIEW) {                             
  8085.                                                                                 
  8086.    (void)GGMivget(gp,"GGSCROLL ", ggscroll, sizeof(ggscroll));                  
  8087.    (void)GGMivget(gp,"GGCURSOR ", ggcursor, sizeof(ggcursor));                  
  8088.                                                                                 
  8089.    BOOLOPTSET(ggscroll, gp->autoscroll, TRUE);                                  
  8090.    BOOLOPTSET(ggcursor, gp->autocursor, FALSE);                                 
  8091.                                                                                 
  8092.  }                                                                              
  8093.                                                                                 
  8094.  return;                                                                        
  8095. }                                                                               
  8096.                                                                                 
  8097. ./   ADD NAME=GGMTNET,SSI=01010055                                              
  8098.                                                                                 
  8099.  /********************************************************************/         
  8100.  /*                                                                  */         
  8101.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8102.  /*                                                                  */         
  8103.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8104.  /*                                                                  */         
  8105.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8106.  /* including the implied warranties of merchantability and fitness, */         
  8107.  /* are expressly denied.                                            */         
  8108.  /*                                                                  */         
  8109.  /* Provided this copyright notice is included, this software may    */         
  8110.  /* be freely distributed and not offered for sale.                  */         
  8111.  /*                                                                  */         
  8112.  /* Changes or modifications may be made and used only by the maker  */         
  8113.  /* of same, and not further distributed.  Such modifications should */         
  8114.  /* be mailed to the author for consideration for addition to the    */         
  8115.  /* software and incorporation in subsequent releases.               */         
  8116.  /*                                                                  */         
  8117.  /********************************************************************/         
  8118.                                                                                 
  8119. #pragma  csect(code,  "GG@TNET ")                                               
  8120. #pragma  csect(static,"GG$TNET ")                                               
  8121. #include "gg.h"                                                                 
  8122.                                                                                 
  8123. /****** Gopher TELNET interface. *************************************/         
  8124.                                                                                 
  8125. Bool                                                                            
  8126. GGMtnet(gp,ip,as_file)                                                          
  8127. Rstruc ggcb        *gp;                                                         
  8128. Rstruc gopherinfo  *ip;                                                         
  8129. Fool                as_file;                                                    
  8130. {                                                                               
  8131.  int                tsorc;                                                      
  8132.  char               tsocmd[256];                                                
  8133.                                                                                 
  8134.  if (as_file) {                                                                 
  8135.    ERR1("TELNET interface cannot be viewed as a file.");                        
  8136.    return FALSE;                                                                
  8137.  }                                                                              
  8138.                                                                                 
  8139.  GGMispf(gp,"CONTROL DISPLAY LINE");                                            
  8140.                                                                                 
  8141.  fprintf(stderr,"Note: Login as user: %s\n\n", ip->path);                       
  8142.                                                                                 
  8143.  if (ip->port==0) sprintf(tsocmd,"%s %s",gp->mytelnet,ip->host);                
  8144.  else sprintf(tsocmd,"%s %s %d",gp->mytelnet,ip->host,ip->port);                
  8145.                                                                                 
  8146.  if ((tsorc = GGMtso(tsocmd)) != 0) {                                           
  8147.    ERR3("Command \"%s\" returned code %d", tsocmd, tsorc);                      
  8148.  }                                                                              
  8149.                                                                                 
  8150.  GGMispf(gp,"CONTROL DISPLAY REFRESH");                                         
  8151.                                                                                 
  8152.  return TRUE;                                                                   
  8153. }                                                                               
  8154.                                                                                 
  8155. ./   ADD NAME=GGMTSO                                                            
  8156.                                                                                 
  8157.  /********************************************************************/         
  8158.  /*                                                                  */         
  8159.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8160.  /*                                                                  */         
  8161.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8162.  /*                                                                  */         
  8163.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8164.  /* including the implied warranties of merchantability and fitness, */         
  8165.  /* are expressly denied.                                            */         
  8166.  /*                                                                  */         
  8167.  /* Provided this copyright notice is included, this software may    */         
  8168.  /* be freely distributed and not offered for sale.                  */         
  8169.  /*                                                                  */         
  8170.  /* Changes or modifications may be made and used only by the maker  */         
  8171.  /* of same, and not further distributed.  Such modifications should */         
  8172.  /* be mailed to the author for consideration for addition to the    */         
  8173.  /* software and incorporation in subsequent releases.               */         
  8174.  /*                                                                  */         
  8175.  /********************************************************************/         
  8176.                                                                                 
  8177.  /********************************************************************/         
  8178.  /*                                                                  */         
  8179.  /* Thanks to Michael Van Norman for this code.                      */         
  8180.  /*                                                                  */         
  8181.  /********************************************************************/         
  8182.                                                                                 
  8183. #pragma  csect(code,  "GG@TSO  ")                                               
  8184. #pragma  csect(static,"GG$TSO  ")                                               
  8185. #include "gg.h"                                                                 
  8186.                                                                                 
  8187. #pragma linkage(ikjeftsr,OS)                                                    
  8188.                                                                                 
  8189. #define _IKJEFTSR_FLAGS_AUTH        0x00000000                                  
  8190. #define _IKJEFTSR_FLAGS_COMMAND     0x00000001                                  
  8191. #define _IKJEFTSR_FLAGS_DUMP        0x00000100                                  
  8192. #define _IKJEFTSR_FLAGS_NODUMP      0x00000000                                  
  8193. #define _IKJEFTSR_FLAGS_PROGRAM     0x00000002                                  
  8194. #define _IKJEFTSR_FLAGS_UNAUTH      0x00010000                                  
  8195.                                                                                 
  8196. /****** Issue TSO command. *******************************************/         
  8197.                                                                                 
  8198. int                                                                             
  8199. GGMtso(command)                                                                 
  8200. char        *command;                                                           
  8201. {                                                                               
  8202.  int         flags         = _IKJEFTSR_FLAGS_COMMAND +                          
  8203.                              _IKJEFTSR_FLAGS_UNAUTH;                            
  8204.  int         commandLength = strlen(command);                                   
  8205.  int         rc            = 0;                                                 
  8206.  int         returnCode    = 0;                                                 
  8207.  int         reasonCode    = 0;                                                 
  8208.  int         abendCode     = 0;                                                 
  8209.                                                                                 
  8210.  static int (*ikjeftsr)() = NULL;                                               
  8211.                                                                                 
  8212.  if (!ikjeftsr) {                                                               
  8213.    int tsoEntryAddress;                                                         
  8214.                                                                                 
  8215.    tsoEntryAddress = 0x00000010;    /* Address of CVT */                        
  8216.    tsoEntryAddress = *(int *)(tsoEntryAddress);                                 
  8217.    tsoEntryAddress += 0x9C;/*       /* Offset of TVT in CVT */                  
  8218.    tsoEntryAddress = *(int *)(tsoEntryAddress);                                 
  8219.    tsoEntryAddress += 0x10;/*       /* TSVTASF-TSVT (from IKJTSVT) */           
  8220.    tsoEntryAddress = *(int *)(tsoEntryAddress);                                 
  8221.    ikjeftsr = (int (*)())(tsoEntryAddress);                                     
  8222.  }                                                                              
  8223.                                                                                 
  8224.  if (!ikjeftsr) {                                                               
  8225.    fprintf(stderr,                                                              
  8226.            "Cannot execute TSO commands, can't fetch IKJEFTSR.\n");             
  8227.    return -2;                                                                   
  8228.  }                                                                              
  8229.                                                                                 
  8230.  rc = (*ikjeftsr)(&flags, command, &commandLength,                              
  8231.                           &returnCode, &reasonCode,                             
  8232.                           (int *)((int)(&abendCode) | 0x80000000));             
  8233.                                                                                 
  8234.  if (rc != 0) {                                                                 
  8235.    if (rc > 4) {                                                                
  8236.      fprintf(stderr,"Command failed:%s\n",command);                             
  8237.      if (rc == 20 && reasonCode == 40)                                          
  8238.           fprintf(stderr,"Command was not found.\n");                           
  8239.      else fprintf(stderr,                                                       
  8240.              "rc=%d,returncode=%d,reasoncode=%d,abendcode=%8.8x\n",             
  8241.              rc, returnCode, reasonCode, abendCode);                            
  8242.    }                                                                            
  8243.    if (abendCode != 0) rc = -1;                                                 
  8244.    else rc = returnCode;                                                        
  8245.  }                                                                              
  8246.                                                                                 
  8247.  return rc;                                                                     
  8248. }                                                                               
  8249.                                                                                 
  8250. ./   ADD NAME=GGMTYPE                                                           
  8251.                                                                                 
  8252.  /********************************************************************/         
  8253.  /*                                                                  */         
  8254.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8255.  /*                                                                  */         
  8256.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8257.  /*                                                                  */         
  8258.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8259.  /* including the implied warranties of merchantability and fitness, */         
  8260.  /* are expressly denied.                                            */         
  8261.  /*                                                                  */         
  8262.  /* Provided this copyright notice is included, this software may    */         
  8263.  /* be freely distributed and not offered for sale.                  */         
  8264.  /*                                                                  */         
  8265.  /* Changes or modifications may be made and used only by the maker  */         
  8266.  /* of same, and not further distributed.  Such modifications should */         
  8267.  /* be mailed to the author for consideration for addition to the    */         
  8268.  /* software and incorporation in subsequent releases.               */         
  8269.  /*                                                                  */         
  8270.  /********************************************************************/         
  8271.                                                                                 
  8272. #pragma  csect(code,  "GG@TYPE ")                                               
  8273. #pragma  csect(static,"GG$TYPE ")                                               
  8274. #include "gg.h"                                                                 
  8275.                                                                                 
  8276. /*********************************************************************/         
  8277.                                                                                 
  8278. char *                                                                          
  8279. GGMtype(gophertype t)                                                           
  8280. {                                                                               
  8281.                                                                                 
  8282.  switch (t) {                                                                   
  8283.    case GOPHER_FILE:        return "File     ";                                 
  8284.    case GOPHER_DIRECTORY:   return "Directory";                                 
  8285.    case GOPHER_CSO:         return "Cso      ";                                 
  8286.    case GOPHER_ERROR:       return "Error    ";                                 
  8287.    case GOPHER_MAC_BINHEX:  return "Binhex   ";                                 
  8288.    case GOPHER_DOS_BINARCH: return "Binarch  ";                                 
  8289.    case GOPHER_UUENCODE:    return "Uuencode ";                                 
  8290.    case GOPHER_WAIS:        return "Index    ";                                 
  8291.    case GOPHER_TELNET:      return "Telnet   ";                                 
  8292.    case GOPHER_TN3270:      return "TN3270   ";                                 
  8293.    case GOPHER_BINARY:      return "Binary   ";                                 
  8294.    case GOPHER_REDUNDANT:   return "Redundant";                                 
  8295.    case GOPHER_WHOIS:       return "Whois    ";                                 
  8296.    default:                 return "Unknown  ";                                 
  8297.  }                                                                              
  8298. }                                                                               
  8299.                                                                                 
  8300. ./   ADD NAME=GGMUNALC                                                          
  8301.                                                                                 
  8302.  /********************************************************************/         
  8303.  /*                                                                  */         
  8304.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8305.  /*                                                                  */         
  8306.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8307.  /*                                                                  */         
  8308.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8309.  /* including the implied warranties of merchantability and fitness, */         
  8310.  /* are expressly denied.                                            */         
  8311.  /*                                                                  */         
  8312.  /* Provided this copyright notice is included, this software may    */         
  8313.  /* be freely distributed and not offered for sale.                  */         
  8314.  /*                                                                  */         
  8315.  /* Changes or modifications may be made and used only by the maker  */         
  8316.  /* of same, and not further distributed.  Such modifications should */         
  8317.  /* be mailed to the author for consideration for addition to the    */         
  8318.  /* software and incorporation in subsequent releases.               */         
  8319.  /*                                                                  */         
  8320.  /********************************************************************/         
  8321.                                                                                 
  8322. #pragma  csect(code,  "GG@UNALC")                                               
  8323. #pragma  csect(static,"GG$UNALC")                                               
  8324. #include "gg.h"                                                                 
  8325.                                                                                 
  8326. /****** Unallocate a data set. ***************************************/         
  8327.                                                                                 
  8328. Bool                                                                            
  8329. GGMunalc(ddname)                                                                
  8330. char         *ddname;                                                           
  8331. {                                                                               
  8332.  __S99parms   stuff99;   /* The manual has it wrong.  No "struct". */           
  8333.  int          rc;                                                               
  8334.  char        *cp;                                                               
  8335.  TEXTUNIT    *tu [2];                                                           
  8336.  TEXTUNIT     tu_ddn;                                                           
  8337.  TEXTUNIT     tu_una;                                                           
  8338.                                                                                 
  8339.  if (!ddname ||                                                                 
  8340.      !*ddname) return TRUE;   /* if no ddname to free, do nothing */            
  8341.                                                                                 
  8342.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  8343.                                                                                 
  8344.  stuff99.__S99RBLN   = 20;                                                      
  8345.  stuff99.__S99VERB   = S99VRBUN;                                                
  8346.  stuff99.__S99FLAG1  = 0;                                                       
  8347.  stuff99.__S99ERROR  = 0;                                                       
  8348.  stuff99.__S99INFO   = 0;                                                       
  8349.  stuff99.__S99TXTPP  = tu;                                                      
  8350.  stuff99.__S99FLAG2  = 0;                                                       
  8351.                                                                                 
  8352.  tu[0] = &tu_ddn;                                                               
  8353.  tu[1] = &tu_una;                                                               
  8354.  *(int *)&tu[1] |= 0x80000000;                                                  
  8355.                                                                                 
  8356.  tu_ddn.key     = DUNDDNAM;                                                     
  8357.  tu_ddn.num     = 1;                                                            
  8358.  tu_ddn.ent.len = strlen(ddname);                                               
  8359.  strcpy(tu_ddn.ent.prm,ddname);                                                 
  8360.                                                                                 
  8361.  tu_una.key     = DUNUNALC;                                                     
  8362.  tu_una.num     = 0;                                                            
  8363.                                                                                 
  8364.  for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);                         
  8365.                                                                                 
  8366.  rc = svc99(&stuff99);                                                          
  8367.                                                                                 
  8368.  if (rc == 0) return TRUE;                                                      
  8369.  else if (stuff99.__S99ERROR == 0x0438) /* not freed, is not allocated*/        
  8370.          return TRUE;                                                           
  8371.  else {                                                                         
  8372.    GGMdfail(rc,&stuff99);                                                       
  8373.    return FALSE;                                                                
  8374.  }                                                                              
  8375. }                                                                               
  8376.                                                                                 
  8377. ./   ADD NAME=GGMVIEW,SSI=010B0041                                              
  8378.                                                                                 
  8379.  /********************************************************************/         
  8380.  /*                                                                  */         
  8381.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1993    */         
  8382.  /*                                                                  */         
  8383.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  8384.  /*                                                                  */         
  8385.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8386.  /* including the implied warranties of merchantability and fitness, */         
  8387.  /* are expressly denied.                                            */         
  8388.  /*                                                                  */         
  8389.  /* Provided this copyright notice is included, this software may    */         
  8390.  /* be freely distributed and not offered for sale.                  */         
  8391.  /*                                                                  */         
  8392.  /* Changes or modifications may be made and used only by the maker  */         
  8393.  /* of same, and not further distributed.  Such modifications should */         
  8394.  /* be mailed to the author for consideration for addition to the    */         
  8395.  /* software and incorporation in subsequent releases.               */         
  8396.  /*                                                                  */         
  8397.  /********************************************************************/         
  8398.                                                                                 
  8399. #pragma  csect(code,  "GG@VIEW ")                                               
  8400. #pragma  csect(static,"GG$VIEW ")                                               
  8401. #include "gg.h"                                                                 
  8402.                                                                                 
  8403. struct browser {                                                                
  8404.    struct gopherinfo    *ip;                                                    
  8405.    struct texthdr       *thp;            /* text header pointer      */         
  8406.    struct textline     **tv;             /* text vector              */         
  8407.                char     *bda;            /* dynamic area address     */         
  8408.                char     *work;           /* find work area address   */         
  8409.                char     *firstpos;       /* beginning of actual data */         
  8410.                char     *lastpos;        /* end of actual data       */         
  8411.                int       depth;          /* dynamic area depth       */         
  8412.                int       lvl;            /* last visible line        */         
  8413.                int       size;           /* dynamic area size        */         
  8414.                int       more_rows;      /* Scroll request row count */         
  8415.                int       rowfactor;      /* # physical rows per line */         
  8416.                int       screenbump;     /* # physical rows * width  */         
  8417.                int       top;            /* top row number           */         
  8418.                int       total;          /* total number of rows     */         
  8419.                int       coloff;         /* offset from LEFT/RIGHT   */         
  8420.                int       cols;           /* 1 if COLS done, else 0   */         
  8421.                int       maxlen;         /* maximum text length      */         
  8422.                int       maxcoloff;      /* maximum right scroll     */         
  8423.                Bool      override_scroll;/* set by some commands     */         
  8424.                Bool      highlighted;    /* set if FIND highlights   */         
  8425.                Bool      reinit_browse;  /* set if text changed      */         
  8426.                Bool      exit_browse;    /* set if browse must exit  */         
  8427.                Bool      find_hit_end;   /* top/bottom of data reach */         
  8428.                int       find_count;     /* used by FIND ALL         */         
  8429.                int       find_row;       /* row where last found     */         
  8430.                int       find_col;       /* col where last found     */         
  8431.                int       found_row;      /* row where last found     */         
  8432.                int       found_col;      /* col where last found     */         
  8433.                int       csrpos;         /* cursor position          */         
  8434.                int       find_csrpos;    /* col where last found     */         
  8435.                int       found_left;     /* pos left of found string */         
  8436.                int       found_right;    /* pos right of found string*/         
  8437.                char      cursor     [9]; /* cursor field name        */         
  8438.                char      find_cursor[9]; /* row where last found     */         
  8439.                char      title     [81]; /* title                    */         
  8440.                char      cols_line [81]; /* cols line                */         
  8441.                char      zcmd      [81]; /* command input            */         
  8442.               };                                                                
  8443.                                                                                 
  8444. /******* EXTRACT command **********************************************/        
  8445.                                                                                 
  8446. static Bool                                                                     
  8447. process_extract_command(gp,bp,operands)                                         
  8448. Rstruc ggcb         *gp;                                                        
  8449. Rstruc browser      *bp;                                                        
  8450. char                *operands;                                                  
  8451. {                                                                               
  8452.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8453.                                                                                 
  8454.  gp->extract_file = NULL;                                                       
  8455.                                                                                 
  8456.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8457.  (void)GGMxtx(gp,ip,EXTRACT_IT);                   /* Extract text */           
  8458.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8459.                                                                                 
  8460.  return TRUE;                                                                   
  8461. }                                                                               
  8462.                                                                                 
  8463. /******* PRINT command ************************************************/        
  8464.                                                                                 
  8465. static Bool                                                                     
  8466. process_print_command(gp,bp,operands)                                           
  8467. Rstruc ggcb         *gp;                                                        
  8468. Rstruc browser      *bp;                                                        
  8469. char                *operands;                                                  
  8470. {                                                                               
  8471.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8472.                                                                                 
  8473.  gp->extract_file = NULL;                                                       
  8474.                                                                                 
  8475.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8476.  (void)GGMxtx(gp,ip,PRINT_IT);                   /* Print text */               
  8477.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8478.                                                                                 
  8479.  return TRUE;                                                                   
  8480. }                                                                               
  8481.                                                                                 
  8482. /******* INFO command. ************************************************/        
  8483.                                                                                 
  8484. static Bool                                                                     
  8485. process_info_command(gp,bp,operands)                                            
  8486. Rstruc ggcb         *gp;                                                        
  8487. Rstruc browser      *bp;                                                        
  8488. char                *operands;                                                  
  8489. {                                                                               
  8490.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8491.                                                                                 
  8492.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  8493.                                                                                 
  8494.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8495.  (void)GGMvtx(gp,NULL,TRUE);              /* View text */                       
  8496.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8497.                                                                                 
  8498.  return TRUE;                                                                   
  8499. }                                                                               
  8500.                                                                                 
  8501. /******* BOOKMARK command. ********************************************/        
  8502.                                                                                 
  8503. static Bool                                                                     
  8504. process_bookmark_command(gp,bp,operands)                                        
  8505. Rstruc ggcb         *gp;                                                        
  8506. Rstruc browser      *bp;                                                        
  8507. char                *operands;                                                  
  8508. {                                                                               
  8509.  Rstruc gopherinfo  *ip = bp->ip;                                               
  8510.                                                                                 
  8511.  if (!GGMinfo(gp,ip)) return FALSE;                                             
  8512.                                                                                 
  8513.  gp->extract_file = NULL;                                                       
  8514.                                                                                 
  8515.  (void)GGMispf(gp,"CONTROL DISPLAY SAVE");                                      
  8516.  (void)GGMxtx(gp,ip,BOOKMARK_IT);       /* save as bookmark */                  
  8517.  (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");                                   
  8518.                                                                                 
  8519.  return TRUE;                                                                   
  8520. }                                                                               
  8521.                                                                                 
  8522. /******* OPTIONS command **********************************************/        
  8523.                                                                                 
  8524. static Bool                                                                     
  8525. process_options_command(gp,bp,operands)                                         
  8526. Rstruc ggcb         *gp;                                                        
  8527. Rstruc browser      *bp;                                                        
  8528. char                *operands;                                                  
  8529. {                                                                               
  8530.                                                                                 
  8531.  GGMdsopt(gp,operands);                                                         
  8532.                                                                                 
  8533.  return TRUE;                                                                   
  8534. }                                                                               
  8535.                                                                                 
  8536. /******* QUIT command *************************************************/        
  8537.                                                                                 
  8538. static Bool                                                                     
  8539. process_quit_command(gp,bp,operands)                                            
  8540. Rstruc ggcb         *gp;                                                        
  8541. Rstruc browser      *bp;                                                        
  8542. char                *operands;                                                  
  8543. {                                                                               
  8544.                                                                                 
  8545.  gp->quit = TRUE;                                                               
  8546.                                                                                 
  8547.  return TRUE;                                                                   
  8548. }                                                                               
  8549.                                                                                 
  8550. /******* COLS command *************************************************/        
  8551.                                                                                 
  8552. static Bool                                                                     
  8553. process_cols_command(gp,bp,operands)                                            
  8554. Rstruc ggcb         *gp;                                                        
  8555. Rstruc browser      *bp;                                                        
  8556. char                *operands;                                                  
  8557. {                                                                               
  8558.                                                                                 
  8559.  bp->cols = 1;                                                                  
  8560.  *bp->cols_line = '\0';                                                         
  8561.  bp->reinit_browse = TRUE;                                                      
  8562.  return TRUE;                                                                   
  8563. }                                                                               
  8564.                                                                                 
  8565. /******* RESET command ************************************************/        
  8566.                                                                                 
  8567. static Bool                                                                     
  8568. process_reset_command(gp,bp,operands)                                           
  8569. Rstruc ggcb         *gp;                                                        
  8570. Rstruc browser      *bp;                                                        
  8571. char                *operands;                                                  
  8572. {                                                                               
  8573.                                                                                 
  8574.  bp->cols = 0;                                                                  
  8575.  *bp->cols_line = '\0';                                                         
  8576.  bp->reinit_browse = TRUE;                                                      
  8577.  return TRUE;                                                                   
  8578. }                                                                               
  8579.                                                                                 
  8580. /******* DISPLAY command **********************************************/        
  8581.                                                                                 
  8582. static Bool                                                                     
  8583. process_display_command(gp,bp,operands)                                         
  8584. Rstruc ggcb         *gp;                                                        
  8585. Rstruc browser      *bp;                                                        
  8586. char                *operands;                                                  
  8587. {                                                                               
  8588.  unsigned int        u;                                                         
  8589.                                                                                 
  8590.  switch (strlen(operands)) {                                                    
  8591.    case 1: gp->text_dispchar = operands[0];                                     
  8592.            break;                                                               
  8593.    case 2: if (1 != sscanf(operands,"%x",&u)) {                                 
  8594.              ERR1("Invalid hex character representation.");                     
  8595.              return FALSE;                                                      
  8596.            }                                                                    
  8597.            gp->text_dispchar = u;                                               
  8598.            break;                                                               
  8599.    default:                                                                     
  8600.            ERR1("A single character must be specified.");                       
  8601.            return FALSE;                                                        
  8602.  }                                                                              
  8603.  bp->reinit_browse = TRUE;                                                      
  8604.  return TRUE;                                                                   
  8605. }                                                                               
  8606.                                                                                 
  8607. /******* LOCATE command ***********************************************/        
  8608.                                                                                 
  8609. static Bool                                                                     
  8610. process_locate_command(gp,bp,operands)                                          
  8611. Rstruc ggcb         *gp;                                                        
  8612. Rstruc browser      *bp;                                                        
  8613. char                *operands;                                                  
  8614. {                                                                               
  8615.  int                 locnum;                                                    
  8616.  char                junk[72];                                                  
  8617.                                                                                 
  8618.  if (1 != sscanf(operands, "%d %s", &locnum, junk)) {                           
  8619.    ERR1("The LOCATE command requires a line number.");                          
  8620.    return FALSE;                                                                
  8621.  }                                                                              
  8622.                                                                                 
  8623.  bp->top = locnum;                                                              
  8624.  bp->more_rows = 0;                                                             
  8625.  bp->override_scroll = TRUE;                                                    
  8626.  bp->reinit_browse = TRUE;                                                      
  8627.  return TRUE;                                                                   
  8628. }                                                                               
  8629.                                                                                 
  8630. /***** Helper functions for FIND **************************************/        
  8631.                                                                                 
  8632. /*--------------------------------------------------------------------*         
  8633.  * Get quoted FIND string.                                            *         
  8634.  *--------------------------------------------------------------------*/        
  8635.                                                                                 
  8636. static char *                                                                   
  8637. get_quoted_find_string(gp,cp,qform)                                             
  8638. Rstruc ggcb         *gp;                                                        
  8639. char                *cp;                                                        
  8640. char                *qform;                                                     
  8641. {                                                                               
  8642.  char                quote     = *cp;                                           
  8643.  char                termchar  = '\0';                                          
  8644.                                                                                 
  8645.  for (cp++;;cp++) {                                                             
  8646.    if (*cp == quote) {                                                          
  8647.      switch (*(cp+1)) {                                                         
  8648.        case '\0':                                                               
  8649.        case ' ':  termchar = '\0'; break;                                       
  8650.        case 'c':                                                                
  8651.        case 'C':  termchar = 'C' ; break;                                       
  8652.        case 't':                                                                
  8653.        case 'T':  termchar = 'T' ; break;                                       
  8654.        case 'x':                                                                
  8655.        case 'X':  termchar = 'X' ; break;                                       
  8656.        case 'p':                                                                
  8657.        case 'P':  termchar = 'P' ; break;                                       
  8658.        default:   continue;                                                     
  8659.      }                                                                          
  8660.      if (termchar) {                                                            
  8661.        switch (*(cp+2)) {                                                       
  8662.          case '\0':                                                             
  8663.          case ' ':  break;                                                      
  8664.          default:   continue;                                                   
  8665.        }                                                                        
  8666.        if (*qform != FIND_QUOTED) {                                             
  8667.          ERR1(                                                                  
  8668.       "Invalid string; Do not surround a quoted string with letters.");         
  8669.          *qform = FIND_BADFORM;                                                 
  8670.          return NULL;                                                           
  8671.        }                                                                        
  8672.        else {                                                                   
  8673.          switch (termchar) {                                                    
  8674.            case 'C': *qform = FIND_C; break;                                    
  8675.            case 'T': *qform = FIND_T; break;                                    
  8676.            case 'X': *qform = FIND_X; break;                                    
  8677.            case 'P': *qform = FIND_P; break;                                    
  8678.          }                                                                      
  8679.          *cp = '\0'; /* kill the quote because it's the character */            
  8680.          cp++;       /* that the caller will kill, not the quote */             
  8681.        }                                                                        
  8682.      }                                                                          
  8683.      break;                                                                     
  8684.    }                                                                            
  8685.    else if (!*cp) {                                                             
  8686.      ERR1(                                                                      
  8687.      "Missing quote; The FIND command requires balanced quote marks.");         
  8688.      *qform = FIND_BADFORM;                                                     
  8689.      return NULL;                                                               
  8690.    }                                                                            
  8691.  }                                                                              
  8692.  return cp;                                                                     
  8693. }                                                                               
  8694.                                                                                 
  8695. /*--------------------------------------------------------------------*         
  8696.  * Get FIND operand.                                                  *         
  8697.  *--------------------------------------------------------------------*/        
  8698.                                                                                 
  8699. static char *                                                                   
  8700. get_find_operand(gp,opp,qform)                                                  
  8701. Rstruc ggcb     *gp;                                                            
  8702. char           **opp;                                                           
  8703. char            *qform;                                                         
  8704. {                                                                               
  8705.  char           *cp    = *opp;                                                  
  8706.  char           *start = NULL;                                                  
  8707.                                                                                 
  8708.  cp = skip_ISPF_whitespace(cp);                                                 
  8709.                                                                                 
  8710.  if (!*cp) return NULL;                                                         
  8711.  if (*cp == '\'' || *cp == '"') {                                               
  8712.    start = cp+1;                                                                
  8713.    *qform = FIND_QUOTED;                                                        
  8714.    if (!(cp = get_quoted_find_string(gp,cp,qform))) return NULL;                
  8715.  }                                                                              
  8716.  else if ((*(cp+1) == '\'' || *(cp+1) == '"')) {                                
  8717.    switch (*cp) {                                                               
  8718.      case 'c':                                                                  
  8719.      case 'C': *qform = FIND_C; break;                                          
  8720.      case 't':                                                                  
  8721.      case 'T': *qform = FIND_T; break;                                          
  8722.      case 'x':                                                                  
  8723.      case 'X': *qform = FIND_X; break;                                          
  8724.      case 'p':                                                                  
  8725.      case 'P': *qform = FIND_P; break;                                          
  8726.      default:  *qform = FIND_UNQUOTED; break;                                   
  8727.    }                                                                            
  8728.    if (*qform != FIND_UNQUOTED) {                                               
  8729.      cp++;                                                                      
  8730.      start = cp+1;                                                              
  8731.      if (!(cp = get_quoted_find_string(gp,cp,qform))) return NULL;              
  8732.    }                                                                            
  8733.    else {                                                                       
  8734.      start = cp;                                                                
  8735.      find_ISPF_whitespace(cp,start);                                            
  8736.    }                                                                            
  8737.  }                                                                              
  8738.  else {                                                                         
  8739.    start = cp;                                                                  
  8740.    *qform = FIND_UNQUOTED;                                                      
  8741.    find_ISPF_whitespace(cp,start);                                              
  8742.  }                                                                              
  8743.  if (*cp) {                                                                     
  8744.    *cp  = '\0';                                                                 
  8745.    *opp = cp+1;                                                                 
  8746.  }                                                                              
  8747.  else {                                                                         
  8748.    *opp = cp;                                                                   
  8749.  }                                                                              
  8750.  return start;                                                                  
  8751. }                                                                               
  8752.                                                                                 
  8753. /*--------------------------------------------------------------------*         
  8754.  * Find it.                                                           *         
  8755.  *--------------------------------------------------------------------*/        
  8756.                                                                                 
  8757. #define REND                 (r+(*tpp)->tab_expanded_text_length)               
  8758. #define PRECEDED_BY_VERBIAGE (q>r && isalnum(*(q-1)))                           
  8759. #define FOLLOWED_BY_VERBIAGE (q+findlen<REND && isalnum(*(q+findlen)))          
  8760.                                                                                 
  8761. static Bool                                                                     
  8762. find_it(gp,bp,find_string,findlen,                                              
  8763.                           find_type,find_what,find_trans,                       
  8764.                           find_left_bound,find_right_bound)                     
  8765. Rstruc ggcb       *gp;                                                          
  8766. Rstruc browser    *bp;                                                          
  8767. char              *find_string;                                                 
  8768. int                findlen;                                                     
  8769. char               find_type;      /* chars word prefix suffix */               
  8770. char               find_what;      /* next prev first last all */               
  8771. char               find_trans;     /* caps asis generic        */               
  8772. int                find_left_bound;                                             
  8773. int                find_right_bound;                                            
  8774. {                                                                               
  8775.  struct textline **tpp;                                                         
  8776.  char             *p;                                                           
  8777.  char             *q;                                                           
  8778.  char             *r;                                                           
  8779.  int               row;                                                         
  8780.  int               col;                                                         
  8781.  int               complen;                                                     
  8782.  int               lcol;                                                        
  8783.  int               rcol;                                                        
  8784.  int               ecol;                                                        
  8785.  Bool              backward_find;                                               
  8786.                                                                                 
  8787.  lcol = find_left_bound - 1;                                                    
  8788.  rcol = find_right_bound - 1;                                                   
  8789.  row  = bp->find_row;                                                           
  8790.  col  = bp->find_col;                                                           
  8791.                                                                                 
  8792.  switch (find_what) {                                                           
  8793.    case FIND_NEXT:                                                              
  8794.                     if (bp->find_hit_end) {                                     
  8795.                       bp->find_hit_end = FALSE;                                 
  8796.                       row = 0;                                                  
  8797.                       col = lcol;                                               
  8798.                     }                                                           
  8799.                     else if (EQUAL(bp->find_cursor,"GGBDYNA")) {                
  8800.                       row = bp->top+((bp->find_csrpos-1)/80)-bp->cols-1;        
  8801.                       col = (bp->find_csrpos-1) % 80 + bp->coloff;              
  8802.                       if (++col >= bp->maxlen) {                                
  8803.                         row++;                                                  
  8804.                         col = lcol;                                             
  8805.                       }                                                         
  8806.                     }                                                           
  8807.                     else {                                                      
  8808.                       row = bp->top - 1;                                        
  8809.                       if (row < 0) row = 0;                                     
  8810.                       col = lcol;                                               
  8811.                     }                                                           
  8812.                     backward_find = FALSE;                                      
  8813.                     break;                                                      
  8814.    case FIND_PREV:                                                              
  8815.                     if (bp->find_hit_end) {                                     
  8816.                       bp->find_hit_end = FALSE;                                 
  8817.                       row = bp->total - 1;                                      
  8818.                       col = rcol;                                               
  8819.                     }                                                           
  8820.                     else if (EQUAL(bp->find_cursor,"GGBDYNA")) {                
  8821.                       row = bp->top+((bp->find_csrpos-1)/80)-bp->cols-1;        
  8822.                       col = (bp->find_csrpos-1) % 80 + bp->coloff;              
  8823.                       if (--col < 0) {                                          
  8824.                         row--;                                                  
  8825.                         col = rcol;                                             
  8826.                       }                                                         
  8827.                     }                                                           
  8828.                     else {                                                      
  8829.                       row = bp->total - 1;                                      
  8830.                       col = rcol;                                               
  8831.                     }                                                           
  8832.                     backward_find = TRUE;                                       
  8833.                     break;                                                      
  8834.    case FIND_FIRST:                                                             
  8835.                     if (bp->find_hit_end) {                                     
  8836.                       bp->find_hit_end = FALSE;                                 
  8837.                     }                                                           
  8838.                     row = 0;                                                    
  8839.                     col = lcol;                                                 
  8840.                     backward_find = FALSE;                                      
  8841.                     break;                                                      
  8842.    case FIND_LAST:                                                              
  8843.                     if (bp->find_hit_end) {                                     
  8844.                       bp->find_hit_end = FALSE;                                 
  8845.                     }                                                           
  8846.                     row = bp->total - 1;                                        
  8847.                     col = rcol;                                                 
  8848.                     backward_find = TRUE;                                       
  8849.                     break;                                                      
  8850.    case FIND_ALL:                                                               
  8851.                     col++;                                                      
  8852.                     backward_find = FALSE;                                      
  8853.                     break;                                                      
  8854.  }                                                                              
  8855.                                                                                 
  8856.  if (backward_find == FALSE) {                                                  
  8857.    /* forward find */                                                           
  8858.    if (col < lcol) col = lcol;                                                  
  8859.    else if (col > rcol) {                                                       
  8860.      col = lcol;                                                                
  8861.      row++;                                                                     
  8862.    }                                                                            
  8863.    for (tpp = &bp->tv[row]; row < bp->total; tpp++, col=lcol, row++) {          
  8864.      ecol = (*tpp)->tab_expanded_text_length - 1;                               
  8865.      if (ecol > rcol) ecol = rcol;                                              
  8866.      if (col > ecol) continue;                                                  
  8867.      p = (*tpp)->tab_expanded_text;                                             
  8868.      if (find_trans == FIND_CAPS) {                                             
  8869.        copy_uppercase(bp->work,p);                                              
  8870.        r = bp->work;                                                            
  8871.      }                                                                          
  8872.      else r = p;                                                                
  8873.      complen = ecol-col+1;                                                      
  8874.      for (q = r + col;;q++) {                                                   
  8875.        q = memchr(q,find_string[0],complen);                                    
  8876.        if (!q) break;                                                           
  8877.        col = q - r;                                                             
  8878.        complen = ecol-col+1;                                                    
  8879.        if (complen < findlen) break;                                            
  8880.        if (!memcmp(q,find_string,findlen)) {                                    
  8881.          switch (find_type) {                                                   
  8882.            case FIND_CHARS:  break;                                             
  8883.            case FIND_WORD:                                                      
  8884.                 if (PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)               
  8885.                     continue;                                                   
  8886.                 break;                                                          
  8887.            case FIND_PREFIX:                                                    
  8888.                 if (PRECEDED_BY_VERBIAGE || !FOLLOWED_BY_VERBIAGE)              
  8889.                     continue;                                                   
  8890.                 break;                                                          
  8891.            case FIND_SUFFIX:                                                    
  8892.                 if (!PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)              
  8893.                    continue;                                                    
  8894.                 break;                                                          
  8895.          }                                                                      
  8896.          bp->find_row = row;                                                    
  8897.          bp->find_col = col;                                                    
  8898.          return TRUE;                                                           
  8899.        }                                                                        
  8900.      }                                                                          
  8901.    }                                                                            
  8902.    bp->find_row = 0;                                                            
  8903.    bp->find_col = 0;                                                            
  8904.    bp->find_hit_end = TRUE;                                                     
  8905.    return FALSE;                                                                
  8906.  }                                                                              
  8907.  else {                                                                         
  8908.    /* backward find */                                                          
  8909.    if (row >= bp->total) row = bp->total - 1;                                   
  8910.    if (col > rcol-findlen+1) col = rcol-findlen+1;                              
  8911.    else if (col < lcol) {                                                       
  8912.      col = rcol-findlen+1;                                                      
  8913.      row--;                                                                     
  8914.    }                                                                            
  8915.    for (tpp=&bp->tv[row]; row >= 0; tpp--, col=rcol-findlen+1, row--) {         
  8916.      ecol = (*tpp)->tab_expanded_text_length - 1;                               
  8917.      if (ecol > rcol) ecol = rcol;                                              
  8918.      if (col > ecol) col = ecol;                                                
  8919.      p = (*tpp)->tab_expanded_text;                                             
  8920.      if (find_trans == FIND_CAPS) {                                             
  8921.        copy_uppercase(bp->work,p);                                              
  8922.        r = bp->work;                                                            
  8923.      }                                                                          
  8924.      else r = p;                                                                
  8925.      for (q = r + col; q >= r; q--) {                                           
  8926.        if (!memcmp(q,find_string,findlen)) {                                    
  8927.          switch (find_type) {                                                   
  8928.            case FIND_CHARS:  break;                                             
  8929.            case FIND_WORD:                                                      
  8930.                 if (PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)               
  8931.                     continue;                                                   
  8932.                 break;                                                          
  8933.            case FIND_PREFIX:                                                    
  8934.                 if (PRECEDED_BY_VERBIAGE || !FOLLOWED_BY_VERBIAGE)              
  8935.                     continue;                                                   
  8936.                 break;                                                          
  8937.            case FIND_SUFFIX:                                                    
  8938.                 if (!PRECEDED_BY_VERBIAGE || FOLLOWED_BY_VERBIAGE)              
  8939.                    continue;                                                    
  8940.                 break;                                                          
  8941.          }                                                                      
  8942.          col = q - r;                                                           
  8943.          bp->find_row = row;                                                    
  8944.          bp->find_col = col;                                                    
  8945.          return TRUE;                                                           
  8946.        }                                                                        
  8947.      }                                                                          
  8948.    }                                                                            
  8949.    bp->find_row = bp->total - 1;                                                
  8950.    bp->find_col = bp->maxlen;                                                   
  8951.    bp->find_hit_end = TRUE;                                                     
  8952.    return FALSE;                                                                
  8953.  }                                                                              
  8954.                                                                                 
  8955. }                                                                               
  8956.                                                                                 
  8957. /********* FIND command ***********************************************/        
  8958.                                                                                 
  8959. static Bool                                                                     
  8960. process_find_command(gp,bp,operands)                                            
  8961. Rstruc ggcb         *gp;                                                        
  8962. Rstruc browser      *bp;                                                        
  8963. char                *operands;                                                  
  8964. {                                                                               
  8965.  char        *find_operand [64];                                                
  8966.  char        *show_type;                                                        
  8967.  char        *cp;                                                               
  8968.  char        *opcopy;                                                           
  8969.  char        *op;                                                               
  8970.  char        *p;                                                                
  8971.  char        *q;                                                                
  8972.  char         find_qform   [64];                                                
  8973.  Bool         finderror = FALSE;                                                
  8974.  Bool         out_of_bounds = FALSE;                                            
  8975.  int          find_operand_count;                                               
  8976.  int          ox;                                                               
  8977.  int          find_left_bound;                                                  
  8978.  int          find_right_bound;                                                 
  8979.  int          n;                                                                
  8980.  int          len;                                                              
  8981.  int          findlen;                                                          
  8982.  char         find_what;      /* next prev first last all */                    
  8983.  char         find_type;      /* chars word prefix suffix */                    
  8984.  char         find_trans;     /* caps asis generic        */                    
  8985.  char         find_form;      /* unquoted quoted c x t p  */                    
  8986.  char         ff;             /* unquoted quoted c x t p  */                    
  8987.  Bool         hit_end                = FALSE;                                   
  8988.  Bool         find_string_given      = FALSE;                                   
  8989.  Bool         find_what_given        = FALSE;                                   
  8990.  Bool         find_type_given        = FALSE;                                   
  8991.  Bool         find_left_bound_given  = FALSE;                                   
  8992.  Bool         find_right_bound_given = FALSE;                                   
  8993.  char         operand_copy [81];                                                
  8994.  char         find_string  [81];                                                
  8995.  char         temp         [81];                                                
  8996.  char         show_string [129];                                                
  8997.  char         shortmsg    [129];                                                
  8998.  char         longmsg     [129];                                                
  8999.                                                                                 
  9000.  strcpy(operand_copy,operands);                                                 
  9001.                                                                                 
  9002.  find_operand_count = 0;                                                        
  9003.  for (ox = 0, opcopy = operand_copy; ox < 64; ox++) {                           
  9004.    ff = FIND_UNQUOTED;                                                          
  9005.    op = get_find_operand(gp,&opcopy,&ff);                                       
  9006.    if (ff == FIND_BADFORM) return FALSE;                                        
  9007.    if (!op) break;                                                              
  9008.    find_operand[ox] = op;                                                       
  9009.    find_qform[ox] = ff;                                                         
  9010.    find_operand_count++;                                                        
  9011.  }                                                                              
  9012.                                                                                 
  9013.  if (find_operand_count == 0) {                                                 
  9014.    if (!*gp->text_find_string) {                                                
  9015.      ERR1("The first FIND command requires an operand.");                       
  9016.      return FALSE;                                                              
  9017.    }                                                                            
  9018.    strcpy(find_string,gp->text_find_string);                                    
  9019.    find_what        = gp->text_find_what;                                       
  9020.    find_type        = gp->text_find_type;                                       
  9021.    find_trans       = gp->text_find_trans;                                      
  9022.    find_left_bound  = gp->text_find_left_bound;                                 
  9023.    find_right_bound = gp->text_find_right_bound;                                
  9024.  }                                                                              
  9025.  else {                                                                         
  9026.    find_what        = FIND_NEXT;                                                
  9027.    find_type        = FIND_CHARS;                                               
  9028.    find_trans       = FIND_CAPS;                                                
  9029.    find_left_bound  = 1;                                                        
  9030.    find_right_bound = bp->maxlen;                                               
  9031.    for (ox = 0; ox < find_operand_count; ox++) {                                
  9032.      op = find_operand[ox];                                                     
  9033.      ff = find_qform[ox];                                                       
  9034.      if (ff != FIND_UNQUOTED) {                                                 
  9035.        if (find_string_given) finderror = TRUE;                                 
  9036.        else {                                                                   
  9037.          strcpy(find_string,op);                                                
  9038.          find_form = ff;                                                        
  9039.          find_string_given = TRUE;                                              
  9040.        }                                                                        
  9041.      }                                                                          
  9042.      else {                                                                     
  9043.        copy_uppercase(temp,op);                                                 
  9044.        if (EQUAL(temp,"*")) {                                                   
  9045.          if (find_string_given) finderror = TRUE;                               
  9046.          else {                                                                 
  9047.            strcpy(find_string,gp->text_find_string);                            
  9048.            find_form = ff;                                                      
  9049.            find_string_given = TRUE;                                            
  9050.          }                                                                      
  9051.        }                                                                        
  9052.        else if (find_operand_count == 1) {                                      
  9053.          strcpy(find_string,op);                                                
  9054.          find_form = ff;                                                        
  9055.          find_string_given = TRUE;                                              
  9056.        }                                                                        
  9057.        else if (EQUAL(temp,"NEXT")) {                                           
  9058.          if (find_what_given) finderror = TRUE;                                 
  9059.          else {                                                                 
  9060.            find_what = FIND_NEXT;                                               
  9061.            find_what_given = TRUE;                                              
  9062.          }                                                                      
  9063.        }                                                                        
  9064.        else if (EQUAL(temp,"PREV")) {                                           
  9065.          if (find_what_given) finderror = TRUE;                                 
  9066.          else {                                                                 
  9067.            find_what = FIND_PREV;                                               
  9068.            find_what_given = TRUE;                                              
  9069.          }                                                                      
  9070.        }                                                                        
  9071.        else if (EQUAL(temp,"FIRST")) {                                          
  9072.          if (find_what_given) finderror = TRUE;                                 
  9073.          else {                                                                 
  9074.            find_what = FIND_FIRST;                                              
  9075.            find_what_given = TRUE;                                              
  9076.          }                                                                      
  9077.        }                                                                        
  9078.        else if (EQUAL(temp,"LAST")) {                                           
  9079.          if (find_what_given) finderror = TRUE;                                 
  9080.          else {                                                                 
  9081.            find_what = FIND_LAST;                                               
  9082.            find_what_given = TRUE;                                              
  9083.          }                                                                      
  9084.        }                                                                        
  9085.        else if (EQUAL(temp,"ALL")) {                                            
  9086.          if (find_what_given) finderror = TRUE;                                 
  9087.          else {                                                                 
  9088.            find_what = FIND_ALL;                                                
  9089.            find_what_given = TRUE;                                              
  9090.          }                                                                      
  9091.        }                                                                        
  9092.        else if (EQUAL(temp,"CHARS")) {                                          
  9093.          if (find_type_given) finderror = TRUE;                                 
  9094.          else {                                                                 
  9095.            find_type = FIND_CHARS;                                              
  9096.            find_type_given = TRUE;                                              
  9097.          }                                                                      
  9098.        }                                                                        
  9099.        else if (EQUAL(temp,"WORD")) {                                           
  9100.          if (find_type_given) finderror = TRUE;                                 
  9101.          else {                                                                 
  9102.            find_type = FIND_WORD;                                               
  9103.            find_type_given = TRUE;                                              
  9104.          }                                                                      
  9105.        }                                                                        
  9106.        else if (EQUAL(temp,"PREFIX") || EQUAL(temp,"PRE")) {                    
  9107.          if (find_type_given) finderror = TRUE;                                 
  9108.          else {                                                                 
  9109.            find_type = FIND_PREFIX;                                             
  9110.            find_type_given = TRUE;                                              
  9111.          }                                                                      
  9112.        }                                                                        
  9113.        else if (EQUAL(temp,"SUFFIX") || EQUAL(temp,"SUF")) {                    
  9114.          if (find_type_given) finderror = TRUE;                                 
  9115.          else {                                                                 
  9116.            find_type = FIND_SUFFIX;                                             
  9117.            find_type_given = TRUE;                                              
  9118.          }                                                                      
  9119.        }                                                                        
  9120.        else if (*(temp+strspn(temp,"0123456789")) == '\0') {                    
  9121.          if (find_left_bound_given) {                                           
  9122.            if (find_right_bound_given) finderror = TRUE;                        
  9123.            else {                                                               
  9124.              find_right_bound = atoi(temp);                                     
  9125.              if (find_right_bound > bp->maxlen) out_of_bounds = TRUE;           
  9126.              find_right_bound_given = TRUE;                                     
  9127.            }                                                                    
  9128.          }                                                                      
  9129.          else {                                                                 
  9130.            find_left_bound  = atoi(temp);                                       
  9131.              if (find_right_bound < 1) out_of_bounds = TRUE;                    
  9132.            find_left_bound_given = TRUE;                                        
  9133.          }                                                                      
  9134.        }                                                                        
  9135.        else {                                                                   
  9136.          if (find_string_given) finderror = TRUE;                               
  9137.          else {                                                                 
  9138.            strcpy(find_string,op);                                              
  9139.            find_form = ff;                                                      
  9140.            find_string_given = TRUE;                                            
  9141.          }                                                                      
  9142.        }                                                                        
  9143.      }                                                                          
  9144.    }                                                                            
  9145.  }                                                                              
  9146.                                                                                 
  9147.  if (out_of_bounds) {                                                           
  9148.    ERR2("Invalid bound; Bounds must lie between 1 and %d", bp->maxlen);         
  9149.    return FALSE;                                                                
  9150.  }                                                                              
  9151.                                                                                 
  9152.  if (finderror) {                                                               
  9153.    ERR1("Put string in quotes; Conflicting or unknown parameter.");             
  9154.    return FALSE;                                                                
  9155.  }                                                                              
  9156.                                                                                 
  9157.  len = strlen(find_string);                                                     
  9158.                                                                                 
  9159.  if (find_string_given) bp->find_hit_end = FALSE;                               
  9160.                                                                                 
  9161.  if (find_left_bound_given && find_right_bound_given                            
  9162.      && find_left_bound > find_right_bound) {                                   
  9163.    n = find_left_bound;                                                         
  9164.    find_left_bound = find_right_bound;                                          
  9165.    find_right_bound = n;                                                        
  9166.  }                                                                              
  9167.  else if (find_left_bound_given && !find_right_bound_given) {                   
  9168.    find_right_bound = find_left_bound + len - 1;                                
  9169.  }                                                                              
  9170.                                                                                 
  9171.  if (find_string_given) {                                                       
  9172.    switch (find_form) {                                                         
  9173.      case FIND_UNQUOTED:  find_trans = FIND_CAPS;    break;                     
  9174.      case FIND_QUOTED:    find_trans = FIND_CAPS;    break;                     
  9175.      case FIND_C:         find_trans = FIND_ASIS;    break;                     
  9176.      case FIND_T:         find_trans = FIND_CAPS;    break;                     
  9177.      case FIND_P:         find_trans = FIND_GENERIC; break;                     
  9178.      case FIND_X:         find_trans = FIND_HEX;                                
  9179.         if (len % 2 != 0) {                                                     
  9180.           ERR1("Odd number of characters in hex string.");                      
  9181.           return FALSE;                                                         
  9182.         }                                                                       
  9183.         if (len != strspn(find_string,"0123456789abcdefABCDEF")) {              
  9184.           ERR1("Invalid (non-hex) characters in hex string.");                  
  9185.           return FALSE;                                                         
  9186.         }                                                                       
  9187.         for (p = find_string, q = find_string; *p; p += 2, *q++) {              
  9188.           sprintf(temp,"0x%2.2s",p);                                            
  9189.           sscanf(temp,"%x",&n);                                                 
  9190.           *q = (char)n;                                                         
  9191.         }                                                                       
  9192.         *q = '\0';                                                              
  9193.         len = strlen(find_string);                                              
  9194.         break;                                                                  
  9195.    }                                                                            
  9196.  }                                                                              
  9197.                                                                                 
  9198.  /* Store parameters for next Repeat Find operation. */                         
  9199.                                                                                 
  9200.  strcpy(gp->text_find_string,find_string);                                      
  9201.  switch (find_what) {                                                           
  9202.    case FIND_PREV:                                                              
  9203.    case FIND_LAST:  gp->text_find_what = FIND_PREV; break;                      
  9204.    default:         gp->text_find_what = FIND_NEXT; break;                      
  9205.  }                                                                              
  9206.  gp->text_find_type        = find_type;                                         
  9207.  gp->text_find_trans       = find_trans;                                        
  9208.  gp->text_find_left_bound  = find_left_bound;                                   
  9209.  gp->text_find_right_bound = find_right_bound;                                  
  9210.                                                                                 
  9211.  if (!*find_string) {                                                           
  9212.    ERR1("A null string is not allowed for the FIND command.");                  
  9213.    return FALSE;                                                                
  9214.  }                                                                              
  9215.                                                                                 
  9216.  if (bp->total == 0) {                                                          
  9217.    ERR1("There is no text to search.");                                         
  9218.    return FALSE;                                                                
  9219.  }                                                                              
  9220.                                                                                 
  9221.  strcpy(bp->zcmd,"");                                                           
  9222.                                                                                 
  9223.  switch (find_type) {                                                           
  9224.    case FIND_CHARS:   show_type = "Chars";  break;                              
  9225.    case FIND_WORD:    show_type = "Word";   break;                              
  9226.    case FIND_PREFIX:  show_type = "Prefix"; break;                              
  9227.    case FIND_SUFFIX:  show_type = "Suffix"; break;                              
  9228.    default:           show_type = "Text";   break;                              
  9229.  }                                                                              
  9230.                                                                                 
  9231.  switch (find_trans) {                                                          
  9232.    case FIND_ASIS:    strcpy(show_string+0,"C'");                               
  9233.                       strcpy(show_string+2,find_string);                        
  9234.                       strcat(show_string,"'");                                  
  9235.                       break;                                                    
  9236.    case FIND_GENERIC: strcpy(show_string+0,"P'");                               
  9237.                       strcpy(show_string+2,find_string);                        
  9238.                       strcat(show_string,"'");                                  
  9239.                       break;                                                    
  9240.    case FIND_HEX:     strcpy(show_string+0,"X'");                               
  9241.                       for (p=find_string,q=show_string+2;*p;p++,q+=2) {         
  9242.                         sprintf(q,"%2.2X",*p);                                  
  9243.                       }                                                         
  9244.                       strcat(show_string,"'");                                  
  9245.                       break;                                                    
  9246.    case FIND_CAPS:                                                              
  9247.    default:           strcpy(show_string+0,"'");                                
  9248.                       strcpy(show_string+1,find_string);                        
  9249.                       strcat(show_string,"'");                                  
  9250.                       break;                                                    
  9251.  }                                                                              
  9252.                                                                                 
  9253.  switch (find_trans) {                                                          
  9254.    case FIND_CAPS:                                                              
  9255.         uppercase_in_place(find_string);                                        
  9256.         break;                                                                  
  9257.    case FIND_GENERIC:                                                           
  9258.         ERR1("The P'string' generic format is not supported.");                 
  9259.         return FALSE;                                                           
  9260.  }                                                                              
  9261.                                                                                 
  9262.  hit_end = bp->find_hit_end;                                                    
  9263.  findlen = strlen(find_string);                                                 
  9264.                                                                                 
  9265.  if (find_what == FIND_ALL) {                                                   
  9266.    bp->find_count = 0;                                                          
  9267.    if (!find_it(gp,bp,find_string,findlen,                                      
  9268.                                   find_type,FIND_FIRST,find_trans,              
  9269.                                   find_left_bound, find_right_bound)) {         
  9270.      sprintf(shortmsg,"No %s %s found",show_type,show_string);                  
  9271.      sprintf(longmsg,                                                           
  9272.              "%s %s - not found within columns %d to %d",                       
  9273.              show_type,show_string,find_left_bound,find_right_bound);           
  9274.      ERR3("%24s;%s",shortmsg,longmsg);                                          
  9275.      return FALSE;                                                              
  9276.    }                                                                            
  9277.    bp->found_row = bp->find_row;                                                
  9278.    bp->found_col = bp->find_col;                                                
  9279.    bp->find_count = 1;                                                          
  9280.    while (find_it(gp,bp,find_string,findlen,                                    
  9281.                         find_type,FIND_ALL,find_trans,                          
  9282.                         find_left_bound, find_right_bound)) {                   
  9283.          bp->find_count++;                                                      
  9284.    }                                                                            
  9285.    bp->find_hit_end = FALSE;                                                    
  9286.  }                                                                              
  9287.  else {                                                                         
  9288.    if (!find_it(gp,bp,find_string,findlen,                                      
  9289.                                   find_type,find_what,find_trans,               
  9290.                                   find_left_bound, find_right_bound)) {         
  9291.      if (hit_end) {                                                             
  9292.        sprintf(shortmsg,"No %s %s found",show_type,show_string);                
  9293.        sprintf(longmsg,                                                         
  9294.                "%s %s - not found within columns %d to %d",                     
  9295.                show_type,show_string,find_left_bound,find_right_bound);         
  9296.        ERR3("%24s;%s",shortmsg,longmsg);                                        
  9297.        return FALSE;                                                            
  9298.      }                                                                          
  9299.      else if (gp->text_find_what == FIND_PREV) {                                
  9300.        sprintf(shortmsg,"Top of data reached");                                 
  9301.        sprintf(longmsg,                                                         
  9302.             "%s %s not found.  Use RFIND to continue from bottom.",             
  9303.              show_type, show_string);                                           
  9304.        ERR3("%24s;%s",shortmsg,longmsg);                                        
  9305.      }                                                                          
  9306.      else {                                                                     
  9307.        sprintf(shortmsg,"Bottom of data reached");                              
  9308.        sprintf(longmsg,                                                         
  9309.                "%s %s not found.  Use RFIND to continue from top.",             
  9310.              show_type, show_string);                                           
  9311.        ERR3("%24s;%s",shortmsg,longmsg);                                        
  9312.      }                                                                          
  9313.      return FALSE;                                                              
  9314.    }                                                                            
  9315.    bp->found_row = bp->find_row;                                                
  9316.    bp->found_col = bp->find_col;                                                
  9317.  }                                                                              
  9318.                                                                                 
  9319.  if (bp->found_row + 1 < bp->top                                                
  9320.   || bp->found_row + 1 >= bp->top + bp->lvl - bp->cols) {                       
  9321.    bp->top = bp->found_row + 1 - 1;                                             
  9322.    if (bp->top < 0) bp->top = 0;                                                
  9323.  }                                                                              
  9324.                                                                                 
  9325.  if (bp->found_col < bp->coloff) {                                              
  9326.    bp->coloff = bp->found_col;                                                  
  9327.    *bp->cols_line = '\0';                                                       
  9328.  }                                                                              
  9329.  else if (bp->found_col+len > bp->coloff+80) {                                  
  9330.    bp->coloff = bp->found_col + len - 80;                                       
  9331.    if (bp->coloff < 0) bp->coloff = 0;                                          
  9332.    *bp->cols_line = '\0';                                                       
  9333.  }                                                                              
  9334.                                                                                 
  9335.  strcpy(bp->cursor, "GGBDYNA");                                                 
  9336.  bp->csrpos = 80 * (bp->found_row - bp->top+bp->cols + 1)                       
  9337.               + bp->found_col - bp->coloff + 1;                                 
  9338.                                                                                 
  9339.  bp->found_left = bp->csrpos;                                                   
  9340.  bp->found_right = bp->found_left + len;                                        
  9341.  bp->reinit_browse = TRUE;                                                      
  9342.                                                                                 
  9343.  if (find_what == FIND_ALL) {                                                   
  9344.    sprintf(shortmsg,"%d %s %s",bp->find_count,show_type,show_string);           
  9345.    sprintf(longmsg,                                                             
  9346.            "%s %s found %d times within columns %d to %d",                      
  9347.            show_type,show_string,bp->find_count,                                
  9348.            find_left_bound,find_right_bound);                                   
  9349.    WARN3("%24s;%s",shortmsg,longmsg);                                           
  9350.  }                                                                              
  9351.  else {                                                                         
  9352.    sprintf(shortmsg,"%s %s found",show_type,show_string);                       
  9353.    sprintf(longmsg,                                                             
  9354.            "Search for %s %s within columns %d to %d was successful",           
  9355.            show_type,show_string, find_left_bound,find_right_bound);            
  9356.    WARN3("%24s;%s",shortmsg,longmsg);                                           
  9357.  }                                                                              
  9358.                                                                                 
  9359.  bp->find_row = bp->found_row;                                                  
  9360.  bp->find_col = bp->found_col;                                                  
  9361.  return TRUE;                                                                   
  9362. }                                                                               
  9363.                                                                                 
  9364. /************ Fill browse dynamic area. *******************************/        
  9365.                                                                                 
  9366. static void                                                                     
  9367. fill_browse_dynamic_area(gp,bp)                                                 
  9368. Rstruc ggcb        *gp;                                                         
  9369. Rstruc browser     *bp;                                                         
  9370. {                                                                               
  9371.  struct textline  **tpp  = NULL;                                                
  9372.  register char     *cp   = NULL;                                                
  9373.  register char     *p;                                                          
  9374.  char              *q;                                                          
  9375.  char              *r;                                                          
  9376.  int                i;                                                          
  9377.  int                j;                                                          
  9378.  char               temp[12];                                                   
  9379.                                                                                 
  9380.  static char  top_of_data_line[81] = "\                                         
  9381. ********************************* Top of data \                                 
  9382. **********************************";                                            
  9383.                                                                                 
  9384.  static char  bottom_of_data_line[81] = "\                                      
  9385. ******************************** Bottom of data \                               
  9386. ********************************";                                              
  9387.                                                                                 
  9388.  bp->lastpos = bp->bda + bp->size;                                              
  9389.  bp->total = bp->thp->text_line_count;                                          
  9390.                                                                                 
  9391.  memset(bp->bda,' ',bp->size);                                                  
  9392.                                                                                 
  9393.  if      (bp->more_rows == -MAX_INT)                                            
  9394.          bp->top = 0;                                                           
  9395.  else if (bp->more_rows == MAX_INT)                                             
  9396.          bp->top = bp->total + 2 - bp->lvl + bp->cols;                          
  9397.  else    bp->top += bp->more_rows;                                              
  9398.                                                                                 
  9399.  if (bp->top < 0) bp->top = 0;                                                  
  9400.  if (bp->top > bp->total) bp->top = bp->total + 1;                              
  9401.                                                                                 
  9402.  i  = bp->top;                                                                  
  9403.  p  = bp->bda;                                                                  
  9404.                                                                                 
  9405.  if (bp->cols > 0) {                                                            
  9406.    if (!*bp->cols_line) {                                                       
  9407.      for (j=bp->coloff+1,r=bp->cols_line; j<=bp->coloff+80; j++,r++) {          
  9408.        if (j%10 == 0) {                                                         
  9409.          sprintf(temp,"%d",j%100);                                              
  9410.          *r = temp[0];                                                          
  9411.        }                                                                        
  9412.        else if (j%5 == 0) *r = '+';                                             
  9413.        else *r = '-';                                                           
  9414.      }                                                                          
  9415.    }                                                                            
  9416.    memcpy(p,bp->cols_line,80);                                                  
  9417.    p += 80;                                                                     
  9418.  }                                                                              
  9419.                                                                                 
  9420.  if (i == 0) {                                                                  
  9421.    memcpy(p,top_of_data_line,80);                                               
  9422.    p += 80;                                                                     
  9423.    i++;                                                                         
  9424.  }                                                                              
  9425.                                                                                 
  9426.  bp->firstpos = p;                                                              
  9427.                                                                                 
  9428.  for (tpp=&bp->tv[i-1];i<=bp->total && p<bp->lastpos;i++,tpp++,p+=80) {         
  9429.    if ((*tpp)->tab_expanded_text_length > bp->coloff) {                         
  9430.      cp = (*tpp)->tab_expanded_text + bp->coloff;                               
  9431.      for (j = 0, q = p; *cp && j < 80; j++, q++, cp++) {                        
  9432.        if (*cp > 0xf9 || *cp < 0x40) *q = gp->text_dispchar;                    
  9433.        else *q = *cp;                                                           
  9434.      }                                                                          
  9435.    }                                                                            
  9436.  }                                                                              
  9437.                                                                                 
  9438.  if (p < bp->lastpos) {                                                         
  9439.    memcpy(p,bottom_of_data_line,80);                                            
  9440.  }                                                                              
  9441.                                                                                 
  9442.  return;                                                                        
  9443. }                                                                               
  9444.                                                                                 
  9445. /************ Highlight browse text. **********************************/        
  9446.                                                                                 
  9447. static void                                                                     
  9448. highlight_browse_text(gp,bp)                                                    
  9449. Rstruc ggcb        *gp;                                                         
  9450. Rstruc browser     *bp;                                                         
  9451. {                                                                               
  9452.  char              *p;                                                          
  9453.                                                                                 
  9454.  bp->highlighted = FALSE;                                                       
  9455.                                                                                 
  9456.  if (bp->found_left) {                                                          
  9457.    if (EQUAL(bp->cursor,"GGBDYNA")) {                                           
  9458.      for (p = bp->bda + bp->found_left - 1; p >= bp->firstpos; p--) {           
  9459.        if (*p == ' ') {                                                         
  9460.          *p = DATAOUT_HIGH;                                                     
  9461.          bp->highlighted = TRUE;                                                
  9462.          break;                                                                 
  9463.        }                                                                        
  9464.      }                                                                          
  9465.      for (p = bp->bda + bp->found_right - 1; p <= bp->lastpos; p++) {           
  9466.       if (*p == ' ') {                                                          
  9467.         *p = DATAOUT_LOW;                                                       
  9468.          bp->highlighted = TRUE;                                                
  9469.          break;                                                                 
  9470.        }                                                                        
  9471.      }                                                                          
  9472.    }                                                                            
  9473.  }                                                                              
  9474.                                                                                 
  9475.  bp->found_left = 0;                                                            
  9476.  bp->found_right = 0;                                                           
  9477.                                                                                 
  9478.  return;                                                                        
  9479. }                                                                               
  9480.                                                                                 
  9481. /************ Display browse data. ************************************/        
  9482.                                                                                 
  9483. static void                                                                     
  9484. display_browse_data(gp,bp)                                                      
  9485. Rstruc ggcb        *gp;                                                         
  9486. Rstruc browser     *bp;                                                         
  9487. {                                                                               
  9488.  Rstruc cmddesc    *cdp;                                                        
  9489.  char              *cp;                                                         
  9490.  char              *operands;                                                   
  9491.  int                displayrc;                                                  
  9492.  int                zscrolln;                                                   
  9493.  int                leftcol;                                                    
  9494.  int                rightcol;                                                   
  9495.  int                command_index;                                              
  9496.  Bool               command_processed_ok;                                       
  9497.  Bool               is_max;                                                     
  9498.  Bool               is_scroll_word;                                             
  9499.  Bool               is_scroll_cursor;                                           
  9500.  SCROLL             scroll_amount;                                              
  9501.  char               command    [COMMANDSIZE+1];                                 
  9502.  char               zverb      [16];                                            
  9503.  char               zscrolla   [16];                                            
  9504.  char               longmsg    [73];                                            
  9505.  char               ggbtitle  [129];                                            
  9506.  char               ggbmsg     [81];                                            
  9507.  char               temp1      [81];                                            
  9508.  char               temp2      [81];                                            
  9509.                                                                                 
  9510. static struct cmddesc browse_commands[] = {                                     
  9511.                           {"L          ",process_locate_command   },            
  9512.                           {"LOC        ",process_locate_command   },            
  9513.                           {"LOCATE     ",process_locate_command   },            
  9514.                           {"F          ",process_find_command     },            
  9515.                           {"FIND       ",process_find_command     },            
  9516.                           {"RFIND      ",process_find_command     },            
  9517.                           {"YRFIND     ",process_find_command     },            
  9518.                           {"COL        ",process_cols_command     },            
  9519.                           {"COLS       ",process_cols_command     },            
  9520.                           {"RES        ",process_reset_command    },            
  9521.                           {"RESET      ",process_reset_command    },            
  9522.                           {"NOCOL      ",process_reset_command    },            
  9523.                           {"NOCOLS     ",process_reset_command    },            
  9524.                           {"DISP       ",process_display_command  },            
  9525.                           {"DISPL      ",process_display_command  },            
  9526.                           {"DISPLAY    ",process_display_command  },            
  9527.                           {"EXT        ",process_extract_command  },            
  9528.                           {"EXTR       ",process_extract_command  },            
  9529.                           {"EXTRACT    ",process_extract_command  },            
  9530.                           {"PRT        ",process_print_command    },            
  9531.                           {"PRNT       ",process_print_command    },            
  9532.                           {"PRINT      ",process_print_command    },            
  9533.                           {"INFO       ",process_info_command     },            
  9534.                           {"BOOK       ",process_bookmark_command },            
  9535.                           {"BOOKMARK   ",process_bookmark_command },            
  9536.                           {"OPT        ",process_options_command  },            
  9537.                           {"OPTION     ",process_options_command  },            
  9538.                           {"OPTIONS    ",process_options_command  },            
  9539.                           {"QUIT       ",process_quit_command     },            
  9540.                           {"           ",NULL}                                  
  9541.                          };                                                     
  9542.                                                                                 
  9543.  bp->more_rows = 0;                                                             
  9544.  bp->override_scroll = FALSE;                                                   
  9545.  bp->exit_browse     = FALSE;                                                   
  9546.                                                                                 
  9547.  memset (ggbtitle, '-', 80);                                                    
  9548.  strcpy (ggbtitle, "Browse - ");                                                
  9549.  memcpy (ggbtitle + 9, bp->title, strlen(bp->title));                           
  9550.  *(ggbtitle + 9 + strlen(bp->title)) = ' ';                                     
  9551.                                                                                 
  9552.                                                                                 
  9553.  if (!gp->setmsg) {                                                             
  9554.    leftcol = bp->coloff + 1;                                                    
  9555.    rightcol = bp->coloff + 80;                                                  
  9556.    if (bp->top > bp->total) strcpy(temp1,"");                                   
  9557.    else sprintf(temp1, " Line %d of %d,", bp->top, bp->total);                  
  9558.    if (bp->maxlen <= 80)                                                        
  9559.         sprintf(temp2," Cols %d-%d",leftcol,rightcol);                          
  9560.    else sprintf(temp2," Cols %d-%d of %d",leftcol,rightcol,bp->maxlen);         
  9561.    strcpy(ggbmsg,temp1);                                                        
  9562.    strcat(ggbmsg,temp2);                                                        
  9563.    strcpy (ggbtitle + 79 - strlen(ggbmsg), ggbmsg);                             
  9564.  }                                                                              
  9565.                                                                                 
  9566.  (void)GGMivput(gp,"GGBTITLE ",ggbtitle    ,-1);                                
  9567.  (void)GGMivput(gp,"ZCMD "    ,bp->zcmd    ,-1);                                
  9568.  (void)GGMivput(gp,"GGBDYNA " ,bp->bda     ,bp->size);                          
  9569.  (void)GGMivput(gp,"GGBCUR "  ,bp->cursor  ,-1);                                
  9570.  sprintf(temp1,"%d",bp->csrpos);                                                
  9571.  (void)GGMivput(gp,"GGBPOS  " ,temp1       ,-1);                                
  9572.  (void)GGMivput(gp,"YRFIND "  ,"ALIAS FIND",-1);                                
  9573.                                                                                 
  9574.  displayrc = GGMdispl(gp,"GGMVIEW ");                                           
  9575.                                                                                 
  9576.  if (displayrc > 0) bp->exit_browse = TRUE;                                     
  9577.                                                                                 
  9578.  (void)GGMivput(gp,"YRFIND "  ,"",-1);                                          
  9579.  (void)GGMivget(gp,"GGBCUR  " ,bp->cursor  , 8);                                
  9580.  (void)GGMivget(gp,"ZCMD    " ,bp->zcmd     ,sizeof(bp->zcmd));                 
  9581.  bp->lvl    = GGMiget(gp,"GGBLVL  ");                                           
  9582.  bp->csrpos = GGMiget(gp,"GGBPOS  ");                                           
  9583.                                                                                 
  9584.  strcpy(bp->find_cursor, bp->cursor);                                           
  9585.  bp->find_csrpos = bp->csrpos;                                                  
  9586.  strcpy(bp->cursor,"");                                                         
  9587.  bp->csrpos = 1;                                                                
  9588.  if (bp->highlighted) bp->reinit_browse = TRUE;                                 
  9589.  else                 bp->reinit_browse = FALSE;                                
  9590.                                                                                 
  9591.  if (*bp->zcmd) {                                                               
  9592.                                                                                 
  9593.    memset(command,' ',COMMANDSIZE);                                             
  9594.    command_index = 0;                                                           
  9595.    for (cp = bp->zcmd; *cp && !isspace(*cp); cp++) {                            
  9596.      if (cp >= bp->zcmd+COMMANDSIZE) {                                          
  9597.        ERR1(                                                                    
  9598. "Enter EXTract, PRT, BOOKmark, INFO, OPTions, or a browse command.");           
  9599.        command_processed_ok = FALSE;                                            
  9600.      }                                                                          
  9601.      command[command_index++] = toupper(*cp);                                   
  9602.    }                                                                            
  9603.    while (*cp && isspace(*cp)) cp++;                                            
  9604.                                                                                 
  9605.    for (cdp=browse_commands; *cdp->command_name != ' '; cdp++) {                
  9606.      if (!memcmp(command,cdp->command_name,COMMANDSIZE-1)) {                    
  9607.        command_processed_ok = (cdp->command_processor)(gp,bp,cp);               
  9608.        cdp = NULL;                                                              
  9609.        break;                                                                   
  9610.      }                                                                          
  9611.    }                                                                            
  9612.    if (cdp) {                                                                   
  9613.      ERR1(                                                                      
  9614. "Enter EXTract, PRT, BOOKmark, INFO, OPTions, or a browse command.");           
  9615.      command_processed_ok = FALSE;                                              
  9616.    }                                                                            
  9617.                                                                                 
  9618.    if (command_processed_ok) strcpy(bp->zcmd,"");                               
  9619.                                                                                 
  9620.  }                                                                              
  9621.                                                                                 
  9622.  if (gp->quit || bp->exit_browse) return;                                       
  9623.                                                                                 
  9624.  /* Check scroll request (ZSCROLLA direction, ZSCROLLN number).                 
  9625.   * Skip this if something was done by a command which causes                   
  9626.   * its own pseudo-scrolling to happen (like LOCATE).                           
  9627.   */                                                                            
  9628.                                                                                 
  9629.  if (!bp->override_scroll) {                                                    
  9630.                                                                                 
  9631.    zscrolln = 0;                                                                
  9632.                                                                                 
  9633.    (void)GGMivget(gp,"ZVERB    " ,  zverb    ,sizeof(zverb));                   
  9634.    (void)GGMivget(gp,"ZSCROLLA " ,  zscrolla ,sizeof(zscrolla));                
  9635.    zscrolln = GGMiget(gp,"ZSCROLLN ");                                          
  9636.                                                                                 
  9637.    is_max = FALSE;                                                              
  9638.    is_scroll_word = FALSE;                                                      
  9639.    is_scroll_cursor = FALSE;                                                    
  9640.                                                                                 
  9641.    switch (zscrolla[0]) {                                                       
  9642.      case 'P':                                                                  
  9643.      case 'H':                                                                  
  9644.      case 'D':  is_scroll_word = TRUE;                                          
  9645.                 break;                                                          
  9646.      case 'C':  is_scroll_word = TRUE;                                          
  9647.                 is_scroll_cursor = TRUE;                                        
  9648.                 break;                                                          
  9649.      case 'M':  is_max = TRUE;                                                  
  9650.                 break;                                                          
  9651.    }                                                                            
  9652.                                                                                 
  9653.    if      (EQUAL(zverb,"DOWN"))  scroll_amount = DOWN;                         
  9654.    else if (EQUAL(zverb,"UP"))    scroll_amount = UP;                           
  9655.    else if (EQUAL(zverb,"LEFT"))  scroll_amount = LEFT;                         
  9656.    else if (EQUAL(zverb,"RIGHT")) scroll_amount = RIGHT;                        
  9657.    else                           scroll_amount = NO_SCROLL;                    
  9658.                                                                                 
  9659.                                                                                 
  9660.    switch (scroll_amount) {                                                     
  9661.      case NO_SCROLL:                                                            
  9662.           bp->more_rows = 0;                                                    
  9663.           break;                                                                
  9664.      case DOWN:                                                                 
  9665.           if (is_max) bp->more_rows = MAX_INT;                                  
  9666.           else if (is_scroll_word)                                              
  9667.                       bp->more_rows = zscrolln - bp->cols;                      
  9668.           else        bp->more_rows = zscrolln;                                 
  9669.           bp->reinit_browse = TRUE;                                             
  9670.           break;                                                                
  9671.      case UP:                                                                   
  9672.           if (is_max) bp->more_rows = -MAX_INT;                                 
  9673.           else if (is_scroll_cursor)                                            
  9674.                       bp->more_rows = -zscrolln;                                
  9675.           else if (is_scroll_word)                                              
  9676.                       bp->more_rows = -zscrolln - bp->cols;                     
  9677.           else        bp->more_rows = -zscrolln;                                
  9678.           bp->reinit_browse = TRUE;                                             
  9679.           break;                                                                
  9680.      case LEFT:                                                                 
  9681.           if (is_max) bp->coloff = 0;                                           
  9682.           else        bp->coloff -= zscrolln;                                   
  9683.           if (bp->coloff < 0) bp->coloff = 0;                                   
  9684.           *bp->cols_line = '\0';                                                
  9685.           bp->more_rows = 0;                                                    
  9686.           bp->reinit_browse = TRUE;                                             
  9687.           break;                                                                
  9688.      case RIGHT:                                                                
  9689.           if (is_max) bp->coloff = bp->maxcoloff;                               
  9690.           else        bp->coloff += zscrolln;                                   
  9691.           if (bp->coloff > bp->maxcoloff) bp->coloff = bp->maxcoloff;           
  9692.           *bp->cols_line = '\0';                                                
  9693.           bp->more_rows = 0;                                                    
  9694.           bp->reinit_browse = TRUE;                                             
  9695.           break;                                                                
  9696.    }                                                                            
  9697.  }                                                                              
  9698.                                                                                 
  9699.  return;                                                                        
  9700. }                                                                               
  9701.                                                                                 
  9702. /****** View text in full screen mode (BROWSE replacement) ***********/         
  9703.                                                                                 
  9704. void                                                                            
  9705. GGMview(gp,ip,texthdrp,title)                                                   
  9706. Rstruc ggcb         *gp;                                                        
  9707. Rstruc gopherinfo   *ip;                                                        
  9708. struct texthdr      *texthdrp;                                                  
  9709. char                *title;                                                     
  9710. {                                                                               
  9711.  struct textline    *tp;                                                        
  9712.  struct textline   **tv;                                                        
  9713.  struct textline   **textvector;                                                
  9714.  struct browser     *bp;                                                        
  9715.  struct browser      browserstruct;                                             
  9716.                                                                                 
  9717.  GETMAIN(textvector, struct textline *,                                         
  9718.          texthdrp->text_line_count, "text vector");                             
  9719.  if (!textvector) {                                                             
  9720.    ERR1("Not enough memory to display text.");                                  
  9721.    return;                                                                      
  9722.  }                                                                              
  9723.                                                                                 
  9724.  bp = &browserstruct;                                                           
  9725.  memset(bp,0,sizeof(struct browser));                                           
  9726.  bp->ip = ip;                                                                   
  9727.  bp->thp = texthdrp;                                                            
  9728.  bp->tv = textvector;                                                           
  9729.  strcpy(bp->title,title);                                                       
  9730.  bp->more_rows = -MAX_INT;   /* set initial request to scroll up max */         
  9731.  bp->top       = 0;                                                             
  9732.  bp->find_row  = -1;                                                            
  9733.  bp->find_col  = -1;                                                            
  9734.  bp->csrpos    = 1;                                                             
  9735.  strcpy(bp->cursor,"");                                                         
  9736.  bp->reinit_browse = TRUE;                                                      
  9737.                                                                                 
  9738.  /* Collect text line pointers, skipping suppressed lines. */                   
  9739.                                                                                 
  9740.  bp->maxlen = 0;                                                                
  9741.  for (tp=texthdrp->first_text_line, tv=textvector; tp; tp=tp->next) {           
  9742.    if (tp->text_length >= 0) {                                                  
  9743.      *(tv++) = tp;                                                              
  9744.      if (bp->maxlen < tp->tab_expanded_text_length)                             
  9745.          bp->maxlen = tp->tab_expanded_text_length;                             
  9746.    }                                                                            
  9747.  }                                                                              
  9748.  bp->maxcoloff = bp->maxlen - 80;                                               
  9749.  if (bp->maxcoloff < 0) bp->maxcoloff = 0;                                      
  9750.                                                                                 
  9751.  GETMAIN(bp->work, char *, bp->maxlen+1, "browse work string");                 
  9752.  if (!bp->work) return;                                                         
  9753.                                                                                 
  9754.  (void)GGMispf(gp,                                                              
  9755.          "PQUERY PANEL(GGMVIEW) AREANAME(GGBDYNA) DEPTH(GGBDEPTH)");            
  9756.  if (gp->ispfrc != 0) return;                                                   
  9757.  bp->depth = GGMiget(gp,"GGBDEPTH ");                                           
  9758.  bp->size = bp->depth * 80;                                                     
  9759.  GETMAIN(bp->bda, char *, bp->size+1, "browse dynamic area");                   
  9760.  if (!bp->bda) return;                                                          
  9761.                                                                                 
  9762.  if (!gp->text_dispchar) gp->text_dispchar = '.';                               
  9763.                                                                                 
  9764.  for (;;) {                                                                     
  9765.    if (bp->reinit_browse) {                                                     
  9766.      fill_browse_dynamic_area(gp,bp);                                           
  9767.      highlight_browse_text(gp,bp);                                              
  9768.    }                                                                            
  9769.    display_browse_data(gp,bp);                                                  
  9770.    if (gp->quit || bp->exit_browse) break;                                      
  9771.  }                                                                              
  9772.                                                                                 
  9773.  FREEMAIN(bp->work,"browse work string");                                       
  9774.  FREEMAIN(bp->bda,"browse dynamic area");                                       
  9775.  FREEMAIN(textvector, "text vector");                                           
  9776.                                                                                 
  9777.  return;                                                                        
  9778. }                                                                               
  9779.                                                                                 
  9780. ./   ADD NAME=GGMVTX                                                            
  9781.                                                                                 
  9782.  /********************************************************************/         
  9783.  /*                                                                  */         
  9784.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9785.  /*                                                                  */         
  9786.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9787.  /*                                                                  */         
  9788.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9789.  /* including the implied warranties of merchantability and fitness, */         
  9790.  /* are expressly denied.                                            */         
  9791.  /*                                                                  */         
  9792.  /* Provided this copyright notice is included, this software may    */         
  9793.  /* be freely distributed and not offered for sale.                  */         
  9794.  /*                                                                  */         
  9795.  /* Changes or modifications may be made and used only by the maker  */         
  9796.  /* of same, and not further distributed.  Such modifications should */         
  9797.  /* be mailed to the author for consideration for addition to the    */         
  9798.  /* software and incorporation in subsequent releases.               */         
  9799.  /*                                                                  */         
  9800.  /********************************************************************/         
  9801.                                                                                 
  9802. #pragma  csect(code,  "GG@VTX  ")                                               
  9803. #pragma  csect(static,"GG$VTX  ")                                               
  9804. #include "gg.h"                                                                 
  9805.                                                                                 
  9806. /****** View the lines of text retrieved from the server. ************/         
  9807.                                                                                 
  9808. Bool                                                                            
  9809. GGMvtx(gp,ip,as_file)                                                           
  9810. Rstruc ggcb         *gp;                                                        
  9811. Rstruc gopherinfo   *ip;                                                        
  9812. Fool                 as_file;  /* ignored */                                    
  9813. {                                                                               
  9814.  struct texthdr     *texthdrp;                                                  
  9815.  char                title     [81];                                            
  9816.                                                                                 
  9817.  texthdrp = (ip ? &ip->thdr : &gp->thdr);                                       
  9818.                                                                                 
  9819.  if (!ip) sprintf(title, "GopherServer:%s ",gp->ggserver);                      
  9820.  else     strncpy(title, ip->desc, sizeof(title));                              
  9821.                                                                                 
  9822.  GGMview(gp,ip,texthdrp,title);                                                 
  9823.                                                                                 
  9824.  return;                                                                        
  9825. }                                                                               
  9826.                                                                                 
  9827. ./   ADD NAME=GGMWAIS                                                           
  9828.                                                                                 
  9829.  /********************************************************************/         
  9830.  /*                                                                  */         
  9831.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9832.  /*                                                                  */         
  9833.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9834.  /*                                                                  */         
  9835.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9836.  /* including the implied warranties of merchantability and fitness, */         
  9837.  /* are expressly denied.                                            */         
  9838.  /*                                                                  */         
  9839.  /* Provided this copyright notice is included, this software may    */         
  9840.  /* be freely distributed and not offered for sale.                  */         
  9841.  /*                                                                  */         
  9842.  /* Changes or modifications may be made and used only by the maker  */         
  9843.  /* of same, and not further distributed.  Such modifications should */         
  9844.  /* be mailed to the author for consideration for addition to the    */         
  9845.  /* software and incorporation in subsequent releases.               */         
  9846.  /*                                                                  */         
  9847.  /********************************************************************/         
  9848.                                                                                 
  9849. #pragma  csect(code,  "GG@WAIS ")                                               
  9850. #pragma  csect(static,"GG$WAIS ")                                               
  9851. #include "gg.h"                                                                 
  9852.                                                                                 
  9853. /****** Gopher WAIS interface. *************************************/           
  9854.                                                                                 
  9855. Bool                                                                            
  9856. GGMwais(gp,ip,as_file)                                                          
  9857. Rstruc ggcb        *gp;                                                         
  9858. Rstruc gopherinfo  *ip;                                                         
  9859. Fool                as_file;                                                    
  9860. {                                                                               
  9861.  Rstruc connection *sp;                                                         
  9862.  char              *lp;                                                         
  9863.  char               ggwaisq[256];                                               
  9864.                                                                                 
  9865.  sp = &gp->gopher_connection;                                                   
  9866.                                                                                 
  9867.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  9868.                                                                                 
  9869.  strcpy(ggwaisq,"");                                                            
  9870.                                                                                 
  9871.  GGMispf(gp,"VGET (GGWAISQ) PROFILE");                                          
  9872.                                                                                 
  9873.  if (GGMdispl(gp,"GGMPWAIS") > 0) return FALSE;                                 
  9874.                                                                                 
  9875.  GGMivget(gp,"GGWAISQ ",ggwaisq, sizeof(ggwaisq));                              
  9876.                                                                                 
  9877.  if (!*ip->path) strcpy(gp->gopher_command, ggwaisq);                           
  9878.  else            sprintf(gp->gopher_command,"%s\t%s",ip->path,ggwaisq);         
  9879.                                                                                 
  9880.  gp->ginfo = ip;                                                                
  9881.                                                                                 
  9882.  if (!GGMconn(gp,sp)) return FALSE; /* Connect to gopher server */              
  9883.                                                                                 
  9884.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  9885.                                                                                 
  9886.  GGMclrtx(gp,ip);                  /* Clear text */                             
  9887.                                                                                 
  9888.  sp->receiving_text = TRUE;                                                     
  9889.                                                                                 
  9890.  do {                                                                           
  9891.    if (GGMgsrvl(gp,sp,&lp,TRUE)) {         /* Get server line */                
  9892.      if (lp) {                                                                  
  9893.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  9894.      }                                                                          
  9895.    }                                                                            
  9896.  } while (lp);                            /* until no more lines */             
  9897.                                                                                 
  9898.  if (sp->time_to_go_home) {                                                     
  9899.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  9900.    return FALSE;                                                                
  9901.  }                                                                              
  9902.                                                                                 
  9903.  if (sp->connected_to_server) {                                                 
  9904.    (void)GGMdisc(gp,sp);           /* Disconnect from gopher server */          
  9905.  }                                                                              
  9906.                                                                                 
  9907.  GGMdir(gp,ip,as_file); /* display entries returned from WAIS server */         
  9908.                                                                                 
  9909.  return TRUE;                                                                   
  9910.                                                                                 
  9911. }                                                                               
  9912.                                                                                 
  9913. ./   ADD NAME=GGMWHOIS                                                          
  9914.                                                                                 
  9915.  /********************************************************************/         
  9916.  /*                                                                  */         
  9917.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9918.  /*                                                                  */         
  9919.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  9920.  /*                                                                  */         
  9921.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9922.  /* including the implied warranties of merchantability and fitness, */         
  9923.  /* are expressly denied.                                            */         
  9924.  /*                                                                  */         
  9925.  /* Provided this copyright notice is included, this software may    */         
  9926.  /* be freely distributed and not offered for sale.                  */         
  9927.  /*                                                                  */         
  9928.  /* Changes or modifications may be made and used only by the maker  */         
  9929.  /* of same, and not further distributed.  Such modifications should */         
  9930.  /* be mailed to the author for consideration for addition to the    */         
  9931.  /* software and incorporation in subsequent releases.               */         
  9932.  /*                                                                  */         
  9933.  /********************************************************************/         
  9934.                                                                                 
  9935. #pragma  csect(code,  "GG@WHOIS")                                               
  9936. #pragma  csect(static,"GG$WHOIS")                                               
  9937. #include "gg.h"                                                                 
  9938.                                                                                 
  9939. /****** Gopher WHOIS/FINGER interface. *****************************/           
  9940.                                                                                 
  9941. Bool                                                                            
  9942. GGMwhois(gp,ip,as_file)                                                         
  9943. Rstruc ggcb        *gp;                                                         
  9944. Rstruc gopherinfo  *ip;                                                         
  9945. Fool                as_file;        /* ignored */                               
  9946. {                                                                               
  9947.  Rstruc connection *sp;                                                         
  9948.  char              *lp;                                                         
  9949.  Bool               got_some;                                                   
  9950.  char               ggwhoisq[256];                                              
  9951.                                                                                 
  9952.  sp = &gp->gopher_connection;                                                   
  9953.                                                                                 
  9954.  strcpy(gp->ggserver,ip->host);     /* Specify server to connect to */          
  9955.                                                                                 
  9956.  strcpy(ggwhoisq,"");                                                           
  9957.                                                                                 
  9958.  GGMispf(gp,"VGET (GGWHOISQ) PROFILE");                                         
  9959.                                                                                 
  9960.  if (GGMdispl(gp,"GGMPWHOI") > 0) return FALSE;                                 
  9961.                                                                                 
  9962.  GGMivget(gp,"GGWHOISQ ",ggwhoisq, sizeof(ggwhoisq));                           
  9963.                                                                                 
  9964.  if (!*ip->path) strcpy(gp->gopher_command, ggwhoisq);                          
  9965.  else            sprintf(gp->gopher_command,"%s\t%s",ip->path,ggwhoisq);        
  9966.                                                                                 
  9967.  gp->ginfo = ip;                                                                
  9968.                                                                                 
  9969.  if (!GGMconn(gp,sp)) return FALSE;   /* Connect to gopher server */            
  9970.                                                                                 
  9971.  if (!GGMsockt(gp,sp)) return FALSE;  /* Send socket command */                 
  9972.                                                                                 
  9973.  GGMclrtx(gp,ip);                  /* Clear text */                             
  9974.                                                                                 
  9975.  sp->receiving_text = TRUE;                                                     
  9976.  got_some = FALSE;                                                              
  9977.  do {                                                                           
  9978.    if (GGMgsrvl(gp,sp,&lp,TRUE)) {         /* Get server line */                
  9979.      if (lp) {                                                                  
  9980.        got_some = TRUE;                                                         
  9981.        (void)GGMouttx(gp,lp,ip);          /* Output text line */                
  9982.      }                                                                          
  9983.    }                                                                            
  9984.  } while (lp);                            /* until no more lines */             
  9985.                                                                                 
  9986.  if (!got_some) {                                                               
  9987.    WARN2("No data available from server %s.\n",gp->ggserver);                   
  9988.    return FALSE;                                                                
  9989.  }                                                                              
  9990.                                                                                 
  9991.  if (sp->connected_to_server) {                                                 
  9992.    (void)GGMdisc(gp,sp);         /* Disconnect from gopher server */            
  9993.  }                                                                              
  9994.                                                                                 
  9995.  GGMvtx(gp,ip,as_file);  /* display text from WHOIS/FINGER server */            
  9996.                                                                                 
  9997.  return TRUE;                                                                   
  9998.                                                                                 
  9999. }                                                                               
  10000.                                                                                 
  10001. ./   ADD NAME=GGMXTX,SSI=01030034                                               
  10002.                                                                                 
  10003.  /********************************************************************/         
  10004.  /*                                                                  */         
  10005.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10006.  /*                                                                  */         
  10007.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  10008.  /*                                                                  */         
  10009.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10010.  /* including the implied warranties of merchantability and fitness, */         
  10011.  /* are expressly denied.                                            */         
  10012.  /*                                                                  */         
  10013.  /* Provided this copyright notice is included, this software may    */         
  10014.  /* be freely distributed and not offered for sale.                  */         
  10015.  /*                                                                  */         
  10016.  /* Changes or modifications may be made and used only by the maker  */         
  10017.  /* of same, and not further distributed.  Such modifications should */         
  10018.  /* be mailed to the author for consideration for addition to the    */         
  10019.  /* software and incorporation in subsequent releases.               */         
  10020.  /*                                                                  */         
  10021.  /********************************************************************/         
  10022.                                                                                 
  10023. #pragma  csect(code,  "GG@XTX  ")                                               
  10024. #pragma  csect(static,"GG$XTX  ")                                               
  10025. #include "gg.h"                                                                 
  10026.                                                                                 
  10027. #define XFPUTC(A)     gp->extract_write_error = (fputc((A),xfp) == EOF)         
  10028.                                                                                 
  10029. #define XFWRITE(A,B)  fwrite((A),(B),1,xfp), \                                  
  10030.                       gp->extract_write_error = (ferror(xfp) != 0)              
  10031.                                                                                 
  10032. /****** Extract the lines of server text into a data set. ************/         
  10033.                                                                                 
  10034. Bool                                                                            
  10035. GGMxtx(gp,ip,ex)                                                                
  10036. Rstruc ggcb         *gp;                                                        
  10037. Rstruc gopherinfo   *ip;                                                        
  10038. EXTREQ               ex;                                                        
  10039. {                                                                               
  10040.  FILE               *xfp;                                                       
  10041.  struct texthdr     *thp;                                                       
  10042.  struct textline    *tp;                                                        
  10043.  struct extraction  *ep;                                                        
  10044.  char               *cp;                                                        
  10045.  int                 l;                                                         
  10046.  int                 linelen;                                                   
  10047.  Bool                final;                                                     
  10048.  char                formatted_number [11];                                     
  10049.  struct extraction   the_extraction;                                            
  10050.                                                                                 
  10051.  thp = (ip && ex != BOOKMARK_IT ? &ip->thdr : &gp->thdr);                       
  10052.                                                                                 
  10053.  /* Set article data for message. */                                            
  10054.                                                                                 
  10055.  if (ip) {                                                                      
  10056.    sprintf(formatted_number,"%d",ip->type);                                     
  10057.    (void)GGMivput(gp,"GGTNUM ",  formatted_number, -1);                         
  10058.    (void)GGMivput(gp,"GGTSUBJ ", ip->desc,         -1);                         
  10059.  }                                                                              
  10060.                                                                                 
  10061.  if (gp->extract_file) {                                                        
  10062.    (void)GGMispf(gp,"CONTROL DISPLAY LOCK");                                    
  10063.      switch (ex) {                                                              
  10064.        case PRINT_IT: GGMispf(gp,"DISPLAY PANEL(GGMLPRN2)"); break;             
  10065.        default:       GGMispf(gp,"DISPLAY PANEL(GGMLEXN2)"); break;             
  10066.      }                                                                          
  10067.    xfp = gp->extract_file;                                                      
  10068.    ep = gp->extractionp;                                                        
  10069.  }                                                                              
  10070.  else {                                                                         
  10071.                                                                                 
  10072.    ep = &the_extraction;                                                        
  10073.    memset(ep,0,sizeof(struct extraction));                                      
  10074.    switch (ex) {                                                                
  10075.      case EXTRACT_IT:  ep->mode = SEQ;                                          
  10076.                        strcpy(ep->panelname,"GGMPEXDS");                        
  10077.                        break;                                                   
  10078.      case PRINT_IT:    ep->mode = JES;                                          
  10079.                        strcpy(ep->panelname,"GGMPPRDS");                        
  10080.                        break;                                                   
  10081.      case BOOKMARK_IT: ep->mode = SEQ;                                          
  10082.                        strcpy(ep->panelname,"GGMPBMDS");                        
  10083.                        break;                                                   
  10084.    }                                                                            
  10085.    ep->ex = ex;                                                                 
  10086.                                                                                 
  10087.    if (ip) GGMivput(gp,"GGTSUBJ ",ip->desc,-1);                                 
  10088.    else    GGMivput(gp,"GGTSUBJ ",""      ,-1);                                 
  10089.                                                                                 
  10090.    if (!((xfp=GGMgetds(gp,ep)))) return FALSE;                                  
  10091.                                                                                 
  10092.    gp->extract_tab_expanding          = ep->tab_expanding;                      
  10093.    gp->extract_appending              = ep->appending;                          
  10094.    gp->extract_blank_before_separator = ep->blanking;                           
  10095.    gp->extract_separator_line         = ep->separator;                          
  10096.  }                                                                              
  10097.                                                                                 
  10098.  gp->extract_write_error = FALSE;                                               
  10099.  gp->extract_close_error = FALSE;                                               
  10100.                                                                                 
  10101.  /* If a bookmark, then write gopher menu header only if this is                
  10102.   * a new data set (not appending).                                             
  10103.   */                                                                            
  10104.                                                                                 
  10105.  if (ep->ex == BOOKMARK_IT && !ep->appending) {                                 
  10106.    XFWRITE(MENUIDENT,strlen(MENUIDENT));                                        
  10107.    XFPUTC('\n');                                                                
  10108.  }                                                                              
  10109.                                                                                 
  10110.  /* If append mode, and a separator line was specified, use it. */              
  10111.                                                                                 
  10112.  if (gp->extract_appending) {                                                   
  10113.    XFPUTC('\n');                                                                
  10114.    if (gp->extract_separator_line && *gp->extract_separator_line) {             
  10115.      XFWRITE(gp->extract_separator_line,                                        
  10116.              strlen(gp->extract_separator_line));                               
  10117.      XFPUTC('\n');                                                              
  10118.      if (gp->extract_blank_before_separator) XFPUTC('\n');                      
  10119.    }                                                                            
  10120.  }                                                                              
  10121.                                                                                 
  10122.  linelen = (ex == PRINT_IT ? 120 : 251);                                        
  10123.                                                                                 
  10124.  for (tp = thp->first_text_line;                                                
  10125.       tp && !gp->extract_write_error;                                           
  10126.       tp = tp->next) {                                                          
  10127.    if (tp->text_length == 0) {                                                  
  10128.      XFPUTC('\n');                                                              
  10129.    }                                                                            
  10130.    else if (tp->text_length > 0) {                                              
  10131.      if (gp->extract_tab_expanding) {                                           
  10132.        cp = tp->tab_expanded_text;                                              
  10133.        l  = tp->tab_expanded_text_length;                                       
  10134.      }                                                                          
  10135.      else {                                                                     
  10136.        cp = tp->text;                                                           
  10137.        l  = tp->text_length;                                                    
  10138.      }                                                                          
  10139.      for (; l>0 && !gp->extract_write_error; cp+=linelen, l-=linelen) {         
  10140.        XFWRITE(cp,(l > linelen ? linelen : l));                                 
  10141.        XFPUTC('\n');                                                            
  10142.      }                                                                          
  10143.    }                                                                            
  10144.  }                                                                              
  10145.                                                                                 
  10146.  if (!gp->extract_write_error && ferror(xfp))                                   
  10147.     gp->extract_write_error = TRUE;                                             
  10148.                                                                                 
  10149.  if (!gp->extract_appending || !gp->extract_file) {                             
  10150.    switch (ex) {                                                                
  10151.      case EXTRACT_IT:   final = FALSE; break;                                   
  10152.      case PRINT_IT:     final = TRUE;  break;                                   
  10153.      default:           final = FALSE; break;                                   
  10154.    }                                                                            
  10155.    (ep->closer)(gp,ep,xfp,final);   /* Close the file */                        
  10156.    if (gp->extract_close_error) return FALSE;                                   
  10157.  }                                                                              
  10158.                                                                                 
  10159.  if (!gp->extract_file) {                                                       
  10160.    if (gp->extract_write_error) {                                               
  10161.      ERR2("An error occurred writing to %s.", ep->dsname);                      
  10162.      gp->extract_write_error = TRUE;                                            
  10163.    }                                                                            
  10164.    else switch (ex) {                                                           
  10165.      case EXTRACT_IT:                                                           
  10166.           WARN2("Current text extracted into %s.", ep->dsname);                 
  10167.           break;                                                                
  10168.      case PRINT_IT:                                                             
  10169.           WARN2("Current text printed to %s.", ep->dsname);                     
  10170.           break;                                                                
  10171.      case BOOKMARK_IT:                                                          
  10172.           WARN2("Item stored as bookmark in %s.", ep->dsname);                  
  10173.           break;                                                                
  10174.    }                                                                            
  10175.  }                                                                              
  10176.  if (gp->extract_write_error) return FALSE;                                     
  10177.  else return TRUE;                                                              
  10178. }                                                                               
  10179.                                                                                 
  10180. ./   ADD NAME=GGSERVER,SSI=010E0033                                             
  10181. /*                                                                              
  10182.  ***********************************************************************        
  10183.  *                                                                     *        
  10184.  * GOPHER server, based on the simple TCP/IP server from Shawn Hart at *        
  10185.  * the University of Delaware.                                         *        
  10186.  *                                                                     *        
  10187.  ***********************************************************************        
  10188.  *                                                                              
  10189.  *  This server follows the GOPHER protocols defined by UMN.                    
  10190.  *  For more information, see the ANONYMOUS FTP site at                         
  10191.  *  BOOMBOX.MICRO.UMN.EDU.                                                      
  10192.  *                                                                              
  10193.  ***********************************************************************        
  10194.  *                                                                              
  10195.  * November 1992 - parameters may be passed to the server:                      
  10196.  *                                                                              
  10197.  * -d              run in debug mode                                            
  10198.  *                                                                              
  10199.  ***********************************************************************        
  10200.  *                                                                              
  10201.  * December 1992 - support for SNS/TCPAccess compilation                        
  10202.  *                                                                              
  10203.  ***********************************************************************        
  10204.  */                                                                             
  10205.                                                                                 
  10206. #pragma  csect(code,  "GG@ERVER")                                               
  10207. #pragma  csect(static,"GG$ERVER")                                               
  10208. #include "gg.h"                 /* All system file includes needed. */          
  10209.                                                                                 
  10210. /********************************************************************/          
  10211.                                                                                 
  10212. static int                                                                      
  10213. tcpsetup(int          port,                                                     
  10214.          int          qlen,                                                     
  10215.          int          mtftasks,                                                 
  10216.          FILE        *debugfp)                                                  
  10217. {                                                                               
  10218.  int                  tinitrc;             /* loop counter*/                    
  10219.  int                  sockfd;              /* loop counter*/                    
  10220.  int                  x;                   /* loop counter*/                    
  10221.  struct linger        l;                   /* linger for setsockopt */          
  10222.  struct sockaddr_in   server;          /*server address information */          
  10223.                                                                                 
  10224.  /*    initialize the MTF  environment.                   */                    
  10225.                                                                                 
  10226.  if (debugfp) {                                                                 
  10227.    fprintf(debugfp,"tinit...\n");                                               
  10228.    fflush(debugfp);                                                             
  10229.  }                                                                              
  10230.                                                                                 
  10231.  tinitrc = tinit("GGSTASK", mtftasks);                                          
  10232.                                                                                 
  10233.  if (tinitrc != MTF_OK) {                                                       
  10234.    GGMmtfer(tinitrc, "TINIT");                                                  
  10235.    return -1;                                                                   
  10236.  }                                                                              
  10237.                                                                                 
  10238.  /*       open a TCP socket...                            */                    
  10239.                                                                                 
  10240.  if (debugfp) {                                                                 
  10241.    fprintf(debugfp,"socket...\n");                                              
  10242.    fflush(debugfp);                                                             
  10243.  }                                                                              
  10244.                                                                                 
  10245.  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {                          
  10246.    REPORT_TCP_ERROR("SOCKET - ");                                               
  10247.    return -1;                                                                   
  10248.  };                                                                             
  10249.                                                                                 
  10250.  /*  set the linger option on so we wait for data to be sent... */              
  10251.                                                                                 
  10252.  l.l_onoff  =  1;                                                               
  10253.  l.l_linger =100;           /* wait 100 seconds before giving up */             
  10254.                                                                                 
  10255.  if (debugfp) {                                                                 
  10256.    fprintf(debugfp,"setsockopt (%d, SO_LINGER)...\n",sockfd);                   
  10257.    fflush(debugfp);                                                             
  10258.  }                                                                              
  10259.                                                                                 
  10260.  if (setsockopt(sockfd,SOL_SOCKET,SO_LINGER,(char *)&l,sizeof(l))               
  10261.      < 0) {                                                                     
  10262.    REPORT_TCP_ERROR("SETSOCKOPT - ");                                           
  10263.    return -1;                                                                   
  10264.  }                                                                              
  10265.                                                                                 
  10266.  /*    now bind our local address so that the client can send to us */          
  10267.                                                                                 
  10268.  memset((char *)&server, 0, sizeof(server));                                    
  10269.  server.sin_family           =   AF_INET;                                       
  10270.  server.sin_addr.s_addr      =   INADDR_ANY;                                    
  10271.  server.sin_port             =   htons(port);                                   
  10272.                                                                                 
  10273.  if (debugfp) {                                                                 
  10274.    fprintf(debugfp,"bind (%d)...\n",sockfd);                                    
  10275.    fflush(debugfp);                                                             
  10276.  }                                                                              
  10277.                                                                                 
  10278.  if (Bind(sockfd, &server, sizeof(server)) < 0) {                               
  10279.    REPORT_TCP_ERROR("BIND - ");                                                 
  10280.    return -1;                                                                   
  10281.  }                                                                              
  10282.                                                                                 
  10283.  /*    now set length of the connection queue... */                             
  10284.                                                                                 
  10285.  if (debugfp) {                                                                 
  10286.    fprintf(debugfp,"listen (sockfd=%d, qlen=%d)...\n",sockfd,qlen);             
  10287.    fflush(debugfp);                                                             
  10288.  }                                                                              
  10289.                                                                                 
  10290.  if (listen(sockfd,qlen) != 0) {                                                
  10291.    REPORT_TCP_ERROR("LISTEN -");                                                
  10292.    return -1;                                                                   
  10293.  }                                                                              
  10294.                                                                                 
  10295.  return sockfd;                                                                 
  10296.                                                                                 
  10297. }                                                                               
  10298.                                                                                 
  10299.                                                                                 
  10300. /********************************************************************/          
  10301. /*                                                                              
  10302. *   This routine waits for an exception on the socket.  When one                
  10303. *   occurs (by a subtask's "TAKESOCKET"!) we'll close our (the main             
  10304. *   task's) connection to it.                                                   
  10305. *                                                                               
  10306. *               INPUT   s   pointer to socket descripter.                       
  10307. *               OUTPUT  rc  -1 = connection timed out...                        
  10308. *                            0 = an excption occured!                           
  10309. */                                                                              
  10310. /********************************************************************/          
  10311.                                                                                 
  10312. #ifdef SNSTCPIP                                                                 
  10313.                                                                                 
  10314. static int                                                                      
  10315. closesock(int              newsockfd,                                           
  10316.           int              timeout,                                             
  10317.           FILE            *debugfp)                                             
  10318. {                                                                               
  10319.  if (debugfp) {                                                                 
  10320.    fprintf(debugfp,"close (%d)...\n",newsockfd);                                
  10321.    fflush(debugfp);                                                             
  10322.  }                                                                              
  10323.                                                                                 
  10324.  if (close(newsockfd) < 0) REPORT_TCP_ERROR("CLOSE -");                         
  10325.  return 0;                                                                      
  10326. }                                                                               
  10327.                                                                                 
  10328. #else                                                                           
  10329.                                                                                 
  10330. static int                                                                      
  10331. closesock(int              newsockfd,                                           
  10332.           int              timeout,                                             
  10333.           FILE            *debugfp)                                             
  10334. {                                                                               
  10335.  int                       temps;                                               
  10336.  struct sockaddr           clientaddress;                                       
  10337.  int                       addrlen;                                             
  10338.  int                       maxfdpl;                                             
  10339.  struct fd_set             readmask;                                            
  10340.  struct fd_set             writmask;                                            
  10341.  struct fd_set             exepmask;                                            
  10342.  int                       rc;                                                  
  10343.  struct timeval            time;                                                
  10344.                                                                                 
  10345.  temps = newsockfd;                                                             
  10346.  time.tv_sec = timeout;                                                         
  10347.  time.tv_usec = 0;                                                              
  10348.  maxfdpl = temps + 1;                                                           
  10349.                                                                                 
  10350.  FD_ZERO(&readmask);                                                            
  10351.  FD_ZERO(&writmask);                                                            
  10352.  FD_ZERO(&exepmask);                                                            
  10353.  FD_SET(temps, &exepmask);                                                      
  10354.                                                                                 
  10355.  if (debugfp) {                                                                 
  10356.    fprintf(debugfp,"select (maxfdpl=%d)...\n",maxfdpl);                         
  10357.    fflush(debugfp);                                                             
  10358.  }                                                                              
  10359.                                                                                 
  10360.  rc = select(maxfdpl, &readmask, &writmask, &exepmask, &time);                  
  10361.                                                                                 
  10362.  if (rc < 0) {                                                                  
  10363.    REPORT_TCP_ERROR("SELECT - ");                                               
  10364.    return rc;                                                                   
  10365.  }                                                                              
  10366.  else {                                                                         
  10367.    if (rc == 0) fprintf(stdout,"The GIVESOCKET timed out!\n");                  
  10368.                                                                                 
  10369.    if (debugfp) {                                                               
  10370.      fprintf(debugfp,"close (%d)...\n",newsockfd);                              
  10371.      fflush(debugfp);                                                           
  10372.    }                                                                            
  10373.                                                                                 
  10374.    if (close(newsockfd) < 0) REPORT_TCP_ERROR("CLOSE -");                       
  10375.    return rc;                                                                   
  10376.  }                                                                              
  10377. }                                                                               
  10378.                                                                                 
  10379. #endif                                                                          
  10380.                                                                                 
  10381. /********************************************************************/          
  10382. /*                                                                              
  10383. *       This routine starts a subtask, passing control of a socket              
  10384. *       to it.  It then waits for the subtask to take the socket and            
  10385. *       then closes the socket.                                                 
  10386. *                                                                               
  10387. *       INPUT: newsockfd - socket descriptor to give to subtask.                
  10388. */                                                                              
  10389. /********************************************************************/          
  10390.                                                                                 
  10391. static Bool                                                                     
  10392. spawn(                                                                          
  10393.       int           newsockfd,                                                  
  10394.       int           timeout,                                                    
  10395.  struct recvstruct *recvp,                                                      
  10396.       FILE         *debugfp)                                                    
  10397. {                                                                               
  10398.  int                tschedrc;                                                   
  10399. #ifdef SNSTCPIP                                                                 
  10400.  unsigned long      token;                                                      
  10401. #else                                                                           
  10402.  struct clientid    clid;                                                       
  10403.  char               mysname[8];                                                 
  10404. #endif                                                                          
  10405.                                                                                 
  10406.  if (debugfp) {                                                                 
  10407.    fprintf(debugfp,"getclientid...\n");                                         
  10408.    fflush(debugfp);                                                             
  10409.  }                                                                              
  10410.                                                                                 
  10411. #ifdef SNSTCPIP                                                                 
  10412.                                                                                 
  10413.  token = closepass(newsockfd);                                                  
  10414.  if (debugfp) {                                                                 
  10415.    fprintf(debugfp,"token = %X\n",token);                                       
  10416.    fflush(debugfp);                                                             
  10417.  }                                                                              
  10418.                                                                                 
  10419. #else                                                                           
  10420.                                                                                 
  10421.  memset(&clid,0,sizeof(clid));                                                  
  10422.  if(getclientid(AF_INET,&clid) < 0) {                                           
  10423.    REPORT_TCP_ERROR("GETCLIENTID");                                             
  10424.    return FALSE;                                                                
  10425.  }                                                                              
  10426.                                                                                 
  10427.  if (debugfp) {                                                                 
  10428.    fprintf(debugfp,"client name = %8.8s, subtaskname = %8.8s\n",                
  10429.                    clid.name, clid.subtaskname);                                
  10430.    fflush(debugfp);                                                             
  10431.  }                                                                              
  10432.                                                                                 
  10433.  clid.domain = AF_INET;                                                         
  10434.  memcpy(mysname,clid.subtaskname,8);                                            
  10435.  memcpy(clid.subtaskname,"        ",8);                                         
  10436.                                                                                 
  10437.  if (debugfp) {                                                                 
  10438.    fprintf(debugfp,"givesocket (%d)...\n",newsockfd);                           
  10439.    fflush(debugfp);                                                             
  10440.  }                                                                              
  10441.                                                                                 
  10442.  if(givesocket(newsockfd,&clid) != 0) {                                         
  10443.    REPORT_TCP_ERROR("GIVESOCKET");                                              
  10444.    return FALSE;                                                                
  10445.  }                                                                              
  10446.  memcpy(clid.subtaskname,mysname,8);                                            
  10447.                                                                                 
  10448.  if (debugfp) {                                                                 
  10449.    fprintf(debugfp,"client name = %8.8s, subtaskname = %8.8s\n",                
  10450.                    clid.name, clid.subtaskname);                                
  10451.    fflush(debugfp);                                                             
  10452.  }                                                                              
  10453.                                                                                 
  10454. #endif                                                                          
  10455.                                                                                 
  10456.  if (debugfp) {                                                                 
  10457.    fprintf(debugfp,"tsched...\n");                                              
  10458.    fflush(debugfp);                                                             
  10459.  }                                                                              
  10460.                                                                                 
  10461.  tschedrc = tsched(MTF_ANY,"GGSRECV",                                           
  10462. #ifdef SNSTCPIP                                                                 
  10463.                            token,                                               
  10464. #else                                                                           
  10465.                            newsockfd,                                           
  10466.                            clid,                                                
  10467. #endif                                                                          
  10468.                            recvp,                                               
  10469.                            (debugfp ? 1 : 0));                                  
  10470.                                                                                 
  10471.  if (debugfp) {                                                                 
  10472.    fprintf(debugfp,"tsched completed...rc=%d\n",tschedrc);                      
  10473.    fflush(debugfp);                                                             
  10474.  }                                                                              
  10475.                                                                                 
  10476.  if (tschedrc != 0) {                                                           
  10477.    GGMmtfer(tschedrc,"TSCHED");                                                 
  10478.    return FALSE;                                                                
  10479.  }                                                                              
  10480.                                                                                 
  10481.  if (closesock(newsockfd,timeout,debugfp) < 0) {                                
  10482.    REPORT_TCP_ERROR("close socket");                                            
  10483.    return FALSE;                                                                
  10484.  }                                                                              
  10485.                                                                                 
  10486.  return TRUE;                                                                   
  10487.                                                                                 
  10488. }                                                                               
  10489.                                                                                 
  10490. /******************************************************************/            
  10491.                                                                                 
  10492. static Bool                                                                     
  10493. numparm(                                                                        
  10494.         char *pvar,                                                             
  10495.         char *pval,                                                             
  10496.         int  *ivalp                                                             
  10497.        )                                                                        
  10498. {                                                                               
  10499.  if (*(pval + strspn(pval,"0123456789"))) {                                     
  10500.    fprintf(stdout,"Non-numeric value given for %s: %s\n",                       
  10501.                   pvar, pval);                                                  
  10502.    return FALSE;                                                                
  10503.  }                                                                              
  10504.  else {                                                                         
  10505.   *ivalp = atoi(pval);                                                          
  10506.   return TRUE;                                                                  
  10507.  }                                                                              
  10508. }                                                                               
  10509.                                                                                 
  10510. /******************************************************************/            
  10511.                                                                                 
  10512. int                                                                             
  10513. main(int            argc,                                                       
  10514.          char     **argv)                                                       
  10515. {                                                                               
  10516.  int                trc;               /* return code */                        
  10517.  int                x;                 /* loop counter*/                        
  10518.  int                sockfd;            /* connection socket...*/                
  10519.  int                newsockfd;         /* new connection socket...*/            
  10520.  int                clientlen;         /* new connection socket...*/            
  10521.  int                i;                                                          
  10522.  int                n;                                                          
  10523.  int                ival;                                                       
  10524.  char               cval;                                                       
  10525.  char              *p;                                                          
  10526.  char              *cp;                                                         
  10527.  FILE              *debugfp;                                                    
  10528.  FILE              *pfp;                                                        
  10529.  struct sockaddr_in client;            /* client address information */         
  10530. #ifndef SNSTCPIP                                                                
  10531.  struct clientid    clid;              /* client info for givesocket */         
  10532. #endif                                                                          
  10533.  struct recvstruct  recvtemplate;                                               
  10534.  int                mtftasks;                                                   
  10535.  int                port;                                                       
  10536.  int                qlength;                                                    
  10537.  int                timeout;                                                    
  10538.  char               telnet   [257];                                             
  10539.  char               domain   [257];                                             
  10540.  char                  pline    [RBUFSIZE];                                        
  10541.  char                  pvar     [RBUFSIZE];                                        
  10542.  char               pval     [RBUFSIZE];                                        
  10543.  char               buffer   [255];      /* buffer for input/output*/           
  10544.                                                                                 
  10545. /******************************************************************/            
  10546. /* Set parameter defaults.                                        */            
  10547. /******************************************************************/            
  10548.                                                                                 
  10549.  mtftasks     = MTF_TASKS;                                                      
  10550.  port         = SERV_TCP_PORT;                                                  
  10551.  qlength      = TCP_QUEUE_LENGTH;                                               
  10552.  timeout      = CONNECT_TIME_OUT;                                               
  10553.  COPY(telnet,   TELNET_COMMAND_NAME);                                           
  10554.  COPY(domain,   MY_DOMAIN_SUFFIX);                                              
  10555.                                                                                 
  10556. /******************************************************************/            
  10557. /* Process server parameters.                                     */            
  10558. /******************************************************************/            
  10559.                                                                                 
  10560.  debugfp = NULL;                                                                
  10561.                                                                                 
  10562.  for (i = 1; i < argc; i++) {                                                   
  10563.    p = argv[i];                                                                 
  10564.    if (*p == '-') {                                                             
  10565.      while (*++p) {                                                             
  10566.        switch (toupper(*p)) {                                                   
  10567.          case 'D':  debugfp = fopen(DEBUG_FILE,"w");                            
  10568.                     break;                                                      
  10569.          default:   break;                                                      
  10570.        }                                                                        
  10571.      }                                                                          
  10572.    }                                                                            
  10573.  }                                                                              
  10574.                                                                                 
  10575. /******************************************************************/            
  10576. /*         Read startup parameters from parameter file.           */            
  10577. /******************************************************************/            
  10578.                                                                                 
  10579. /*                                                                              
  10580.  * If dd:GGPARMS is present, then read parameters therefrom.                    
  10581.  * If not, then use defaults.  In any case, defaults will be                    
  10582.  * assigned where a corresponding parameter file line isn't found,              
  10583.  *                                                                              
  10584.  * Syntax of parameter file lines:                                              
  10585.  *                                                                              
  10586.  * VARIABLE value   comments                                                    
  10587.  *                                                                              
  10588.  * e.g.                                                                         
  10589.  *                                                                              
  10590.  * MTFTASKS    8    the number of tasks                                         
  10591.  *                                                                              
  10592.  * Comments are indicated by "!" in col 1.                                      
  10593.  *                                                                              
  10594.  */                                                                             
  10595.                                                                                 
  10596.  pfp = fopen(PARAMETER_FILE,"r");                                               
  10597.  if (!pfp) {                                                                    
  10598.    perror(PARAMETER_FILE);                                                      
  10599.    fprintf(stdout,                                                              
  10600.            "No parameter file.  Using all installed defaults.\n");              
  10601.    fflush(stderr);                                                              
  10602.  }                                                                              
  10603.  else {                                                                         
  10604.    for (;;) {                                                                   
  10605.      fgets(pline, sizeof(pline), pfp);                                          
  10606.      if (ferror(pfp)) {                                                         
  10607.        fprintf(stderr,"Error reading parameters from %s\n",                     
  10608.                       PARAMETER_FILE);                                          
  10609.        fflush(stderr);                                                          
  10610.        break;                                                                   
  10611.      }                                                                          
  10612.      if (feof(pfp)) break;                                                      
  10613.      cp = pline;                     /* Start parameter scan       */           
  10614.      if (*cp == '!') continue;       /* Skip comment               */           
  10615.      *pvar = '\0';                   /* Clear parameter variable   */           
  10616.      sscanf(cp,"%s %n",pvar,&n);     /* Get parameter, bump scan   */           
  10617.      if (!*pvar) continue;           /* If nothing on line, skip   */           
  10618.      uppercase_in_place(pvar);       /* Fold variable name         */           
  10619.      cp += n;                        /* Bump to next word in file  */           
  10620.      *pval = '\0';                   /* Clear parameter value      */           
  10621.      sscanf(cp,"%s %n",pval,&n);     /* Get next word, bump scan   */           
  10622.      if (!*pval) {                                                              
  10623.        fprintf(stdout,"Parameter error: value missing for %s\n",                
  10624.                       pvar);                                                    
  10625.        continue;                                                                
  10626.      }                                                                          
  10627.      fprintf(stderr,"Setting %s to '%s' (%d)\n",pvar,pval,ival);                
  10628.      if      (EQUAL(pvar,"MTFTASKS" )) {                                        
  10629.                                         if (numparm(pvar,pval,&ival))           
  10630.                                            mtftasks = ival;                     
  10631.                                        }                                        
  10632.      else if (EQUAL(pvar,"PORT"     )) {                                        
  10633.                                         if (numparm(pvar,pval,&ival))           
  10634.                                            port     = ival;                     
  10635.                                        }                                        
  10636.      else if (EQUAL(pvar,"QLENGTH"  )) {                                        
  10637.                                         if (numparm(pvar,pval,&ival))           
  10638.                                            qlength  = ival;                     
  10639.                                        }                                        
  10640.      else if (EQUAL(pvar,"TIMEOUT"  )) {                                        
  10641.                                         if (numparm(pvar,pval,&ival))           
  10642.                                            timeout  = ival;                     
  10643.                                        }                                        
  10644.      else if (EQUAL(pvar,"TELNET"   )) {                                        
  10645.                                         uppercase_in_place(pval);               
  10646.                                         COPY(telnet,pval);                      
  10647.                                        }                                        
  10648.      else if (EQUAL(pvar,"DOMAIN"   )) {                                        
  10649.                                         uppercase_in_place(pval);               
  10650.                                         COPY(domain,pval);                      
  10651.                                        }                                        
  10652.      else {                                                                     
  10653.        fprintf(stdout,"Unknown parameter, %s.  Skipping.\n",pvar);              
  10654.      }                                                                          
  10655.    }                                                                            
  10656.    (void)fclose(pfp);                                                           
  10657.  }                                                                              
  10658.                                                                                 
  10659. /******************************************************************/            
  10660. /*         display parameter values in effect                     */            
  10661. /******************************************************************/            
  10662.                                                                                 
  10663.  /* Set defaults to pass to the subtask. */                                     
  10664.                                                                                 
  10665.  memset(&recvtemplate,0,sizeof(struct recvstruct));                             
  10666.                                                                                 
  10667.  recvtemplate.myport       = port;                                              
  10668.  recvtemplate.mytelnet     = telnet;                                            
  10669.  recvtemplate.mydomain     = domain;                                            
  10670.                                                                                 
  10671.  fprintf(stdout,"Parameter values in effect:\n\n");                             
  10672.  fprintf(stdout,"MTFTASKS = %d\n", mtftasks);                                   
  10673.  fprintf(stdout,"QLENGTH  = %d\n", qlength);                                    
  10674.  fprintf(stdout,"TIMEOUT  = %d\n", timeout);                                    
  10675.  fprintf(stdout,"PORT     = %d\n", recvtemplate.myport);                        
  10676.  fprintf(stdout,"TELNET   = %s\n", recvtemplate.mytelnet);                      
  10677.  fprintf(stdout,"DOMAIN   = %s\n", recvtemplate.mydomain);                      
  10678.  fprintf(stdout,"\n");                                                          
  10679.                                                                                 
  10680.  fflush(stdout);                                                                
  10681.                                                                                 
  10682. /******************************************************************/            
  10683. /*         set up the connection to the socket...                 */            
  10684. /******************************************************************/            
  10685.                                                                                 
  10686.  sockfd = tcpsetup(port,qlength,mtftasks,debugfp);                              
  10687.  if (sockfd < 0) {                                                              
  10688.    fprintf(stdout,"Could not set up the TCP/IP environment!\n");                
  10689.    exit(16);                                                                    
  10690.  }                                                                              
  10691.                                                                                 
  10692. /******************************************************************/            
  10693. /*         Now loop, waiting for a connection request.            */            
  10694. /******************************************************************/            
  10695.                                                                                 
  10696.  clientlen = sizeof(client);                                                    
  10697.  x = 0;                                                                         
  10698.  for (;;) {                                                                     
  10699.                                                                                 
  10700.    if (debugfp) {                                                               
  10701.      fprintf(debugfp,"accept (%d)...\n",sockfd);                                
  10702.      fflush(debugfp);                                                           
  10703.    }                                                                            
  10704.                                                                                 
  10705.    if ((newsockfd=Accept(sockfd,&client,&clientlen)) == -1) {                   
  10706.      REPORT_TCP_ERROR("ACCEPT - ");                                             
  10707.      exit(8);                                                                   
  10708.    }                                                                            
  10709.    if (debugfp) {                                                               
  10710.      fprintf(debugfp,"newsockfd=%d...\n",newsockfd);                            
  10711.      fflush(debugfp);                                                           
  10712.    }                                                                            
  10713.                                                                                 
  10714.    x++;                                                                         
  10715.    if (!spawn(newsockfd,timeout,&recvtemplate,debugfp)) {                       
  10716.      fprintf(stdout,"spawn failed for socket %d\n",newsockfd);                  
  10717.      exit(8);                                                                   
  10718.    }                                                                            
  10719.    else {                                                                       
  10720.      if (debugfp) {                                                             
  10721.        fprintf(debugfp,"spawn OK for socket %d\n",newsockfd);                   
  10722.        fflush(debugfp);                                                         
  10723.      }                                                                          
  10724.    }                                                                            
  10725.  }                                                                              
  10726.                                                                                 
  10727. /******************************************************************/            
  10728. /*         Wait for all pending tasks to complete (should never   */            
  10729. /*         run, since I haven't added PURGE support yet...)       */            
  10730. /*         then shut down subtasks.                               */            
  10731. /******************************************************************/            
  10732.                                                                                 
  10733.  if (debugfp) {                                                                 
  10734.    fprintf(debugfp,"tsyncro...\n");                                             
  10735.    fflush(debugfp);                                                             
  10736.  }                                                                              
  10737.                                                                                 
  10738.  trc = tsyncro(MTF_ALL);                                                        
  10739.  if (trc != 0) {                                                                
  10740.    GGMmtfer(trc,"TSYNCRO");                                                     
  10741.  }                                                                              
  10742.                                                                                 
  10743.  if (debugfp) {                                                                 
  10744.    fprintf(debugfp,"tterm...\n");                                               
  10745.    fflush(debugfp);                                                             
  10746.  }                                                                              
  10747.                                                                                 
  10748.  trc = tterm();                                                                 
  10749.  if (trc != 4) {                                                                
  10750.    GGMmtfer(trc,"TTERM");                                                       
  10751.    exit(8);                                                                     
  10752.  }                                                                              
  10753.                                                                                 
  10754.  if (debugfp) fclose(debugfp);                                                  
  10755.                                                                                 
  10756.  exit(0);                                                                       
  10757.                                                                                 
  10758. }                                                                               
  10759. ./   ADD NAME=GGSTASK,SSI=01010047                                              
  10760.                                                                                 
  10761.  /********************************************************************/         
  10762.  /*                                                                  */         
  10763.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  10764.  /*                                                                  */         
  10765.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10766.  /* including the implied warranties of merchantability and fitness, */         
  10767.  /* are expressly denied.                                            */         
  10768.  /*                                                                  */         
  10769.  /* Provided this copyright notice is included, this software may    */         
  10770.  /* be freely distributed and not offered for sale.                  */         
  10771.  /*                                                                  */         
  10772.  /* Changes or modifications may be made and used only by the maker  */         
  10773.  /* of same, and not further distributed.  Such modifications should */         
  10774.  /* be mailed to the author for consideration for addition to the    */         
  10775.  /* software and incorporation in subsequent releases.               */         
  10776.  /*                                                                  */         
  10777.  /********************************************************************/         
  10778.                                                                                 
  10779. #pragma  csect(code,  "GGSTASK ")                                               
  10780. #pragma  csect(static,"GG$TASK ")                                               
  10781.                                                                                 
  10782. #include "gg.h"                                                                 
  10783.                                                                                 
  10784. /*=================================================================*/           
  10785.                                                                                 
  10786. /*******************************************************************/           
  10787. /*                                                                 */           
  10788. /*    this is a debugging routine;  it looks at the status of a    */           
  10789. /*    socket.                                                      */           
  10790. /*******************************************************************/           
  10791.                                                                                 
  10792. static void                                                                     
  10793. lookatsocket(int sockfd)                                                        
  10794. {                                                                               
  10795.  int             rc;                       /* return code */                    
  10796.  int             length;                   /* length variable */                
  10797.  int             option;                                                        
  10798.  int             x;                                                             
  10799.  struct linger   l;                        /* linger structure */               
  10800.  char            buffer[RBUFSIZE];                                              
  10801.                                                                                 
  10802.  length = sizeof(l);                                                            
  10803.  if (Getsockopt(sockfd,SOL_SOCKET, SO_LINGER,&l,&length)==0) {                  
  10804.    printf("l_onoff=%d\n",l.l_onoff);                                            
  10805.    printf("l_linger=%d\n",l.l_linger);                                          
  10806.  }                                                                              
  10807.  else REPORT_TCP_ERROR("GETSOCKOPT");                                           
  10808.                                                                                 
  10809.  length = sizeof(option);                                                       
  10810.  if (Getsockopt(sockfd,SOL_SOCKET, SO_ERROR,&option,&length)==0) {              
  10811.    printf("so_error=%d\n",option);                                              
  10812.  }                                                                              
  10813.  else REPORT_TCP_ERROR("GETSOCKOPT");                                           
  10814.                                                                                 
  10815.  if (fcntl(sockfd,F_SETFL,FNDELAY)!=0) REPORT_TCP_ERROR("FCNTL");               
  10816.                                                                                 
  10817.  length = recv(sockfd,buffer,sizeof(buffer)-1,0);                               
  10818.  if (length == -1) {                                                            
  10819.    if (errno != EWOULDBLOCK) REPORT_TCP_ERROR("recv");                          
  10820.  }                                                                              
  10821.  else {                                                                         
  10822.    buffer[sizeof(buffer)-1] = 0;                                                
  10823.    printf("buffer =%s\n",buffer);                                               
  10824.    for (x=0;x<length;x++) printf("%x ",buffer[x]);                              
  10825.    printf("\n");                                                                
  10826.  }                                                                              
  10827.                                                                                 
  10828. }                                                                               
  10829.                                                                                 
  10830. /*******************************************************************/           
  10831.                                                                                 
  10832. /**************************************************************/                
  10833. /*    this routine processes the data once a connection       */                
  10834. /*    has been accepted.  It just takes the data sent by the  */                
  10835. /*    client and prints it to sysprint, then sends it back    */                
  10836. /*    to the client.                                          */                
  10837. /*                                                            */                
  10838. /*             INPUT:   newsockfd  - socket descriptor        */                
  10839. /*                      clid       - takesocket structure...  */                
  10840. /**************************************************************/                
  10841.                                                                                 
  10842. void                                                                            
  10843. GGSrecv(                                                                        
  10844. #ifdef SNSTCPIP                                                                 
  10845.  unsigned long      token,                                                      
  10846. #else                                                                           
  10847.  int                newsockfd,                                                  
  10848.  struct clientid    clid,                                                       
  10849. #endif                                                                          
  10850.  struct recvstruct *recvtp,                                                     
  10851.  int                is_debug                                                    
  10852.        )                                                                        
  10853. {                                                                               
  10854.  struct recvstruct *R;                                                          
  10855.  struct hostent    *hostentp;                                                   
  10856.  char              *bufptr;   /* pointer into buffer strings         */         
  10857.  char              *hp;                                                         
  10858.  char             **halias;                                                     
  10859.  int                retcode;  /* return code                         */         
  10860.  int                len;      /* length of the buffer we're sent     */         
  10861.  int                x;        /* loop counter                        */         
  10862.  int                addrlen;  /* length of client address socket     */         
  10863.  int                hostlen;                                                    
  10864.  int                domslen;                                                    
  10865.  struct sockaddr_in clientaddress; /* address of client              */         
  10866.  struct recvstruct  r;                                                          
  10867.  time_t             timeval;                                                    
  10868.  struct tm         *tmp;                                                        
  10869.  char               outbuf[RBUFSIZE];  /* hold an output string */              
  10870.  char               timestamp[20];                                              
  10871.                                                                                 
  10872.  /* Initialize recv struct with values passed from main task. */                
  10873.                                                                                 
  10874.  memcpy(&r, recvtp, sizeof(struct recvstruct));                                 
  10875.  R = &r;                                                                        
  10876.                                                                                 
  10877. #ifdef SNSTCPIP                                                                 
  10878.                                                                                 
  10879.  if (is_debug) {                                                                
  10880.    fprintf(stdout,"openold (token=%X)...\n",token);                             
  10881.    fflush(stdout);                                                              
  10882.  }                                                                              
  10883.  s0skcfg.exitfunc = NULL; /* Set exit address to NULL */                        
  10884.  R->sockfd = openold(token);                                                    
  10885.  if (is_debug) {                                                                
  10886.    fprintf(stdout,"sockfd from openold is %d\n", R->sockfd);                    
  10887.    fflush(stdout);                                                              
  10888.  }                                                                              
  10889.  if(R->sockfd < 0) {                                                            
  10890.    REPORT_TCP_ERROR("OPENOLD");                                                 
  10891.    fflush(stderr);                                                              
  10892.    return;                                                                      
  10893.  }                                                                              
  10894.                                                                                 
  10895. #else                                                                           
  10896.                                                                                 
  10897.  if (is_debug) {                                                                
  10898.    fprintf(stdout,"takesocket (newsockfd=%d)...\n",newsockfd);                  
  10899.    fprintf(stdout,"name is %8.8s, subtaskname is %8.8s\n",                      
  10900.                   clid.name,clid.subtaskname);                                  
  10901.    fflush(stdout);                                                              
  10902.  }                                                                              
  10903.                                                                                 
  10904.  R->sockfd = takesocket(&clid,newsockfd);                                       
  10905.  if (is_debug) {                                                                
  10906.    fprintf(stdout,"sockfd from takesocket is %d\n", R->sockfd);                 
  10907.    fflush(stdout);                                                              
  10908.  }                                                                              
  10909.  if(R->sockfd < 0) {                                                            
  10910.    REPORT_TCP_ERROR("TAKESOCKET");                                              
  10911.    return;                                                                      
  10912.  }                                                                              
  10913.                                                                                 
  10914. #endif                                                                          
  10915.                                                                                 
  10916.  time(&timeval);                                                                
  10917.  tmp = localtime(&timeval);                                                     
  10918.  sprintf(timestamp,"%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d",                       
  10919.          tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_year,                           
  10920.          tmp->tm_hour, tmp->tm_min, tmp->tm_sec);                               
  10921.                                                                                 
  10922.  if (is_debug) {                                                                
  10923.    fprintf(stdout,"getpeername...\n");                                          
  10924.    fflush(stdout);                                                              
  10925.  }                                                                              
  10926.                                                                                 
  10927.  addrlen = sizeof(clientaddress);                                               
  10928.  if(Getpeername(R->sockfd,&clientaddress,&addrlen)!=0) {                        
  10929.    REPORT_TCP_ERROR("GETPEERNAME");                                             
  10930.    printf("could not determine client address for socket %d\n",                 
  10931.           R->sockfd);                                                           
  10932.  }                                                                              
  10933.                                                                                 
  10934.  /* Try to get the name of the client host. */                                  
  10935.                                                                                 
  10936.  strcpy(R->hostname,"{UNKNOWN HOST NAME}");                                     
  10937.                                                                                 
  10938.  if (is_debug) {                                                                
  10939.    fprintf(stdout,"gethostbyaddr...\n");                                        
  10940.    fflush(stdout);                                                              
  10941.  }                                                                              
  10942.                                                                                 
  10943.  hostentp = Gethostbyaddr(&clientaddress.sin_addr,                              
  10944.                           sizeof(clientaddress.sin_addr),                       
  10945.                           AF_INET);                                             
  10946.                                                                                 
  10947.  if (hostentp && hostentp->h_name) {                                            
  10948.    memcpy(&R->clienthostent, hostentp, sizeof(struct hostent));                 
  10949.    strcpy(R->hostname,hostentp->h_name);                                        
  10950.    uppercase_in_place(R->hostname);                                             
  10951.  }                                                                              
  10952.                                                                                 
  10953.  strcpy(R->hosttest,R->hostname);                                               
  10954.                                                                                 
  10955.  hostlen = strlen(R->hosttest);                                                 
  10956.  domslen = strlen(R->mydomain);                                                 
  10957.  if (hostlen > domslen) {                                                       
  10958.    hp = R->hosttest + hostlen - domslen;                                        
  10959.    if (!memcmp(hp, R->mydomain, domslen)) {                                     
  10960.      *hp = '\0';                                                                
  10961.    }                                                                            
  10962.  }                                                                              
  10963.                                                                                 
  10964.  printf("%s Connection from %s (%s, aka %s).  Socket %d\n",                     
  10965.         timestamp,                                                              
  10966.         inet_ntoa(clientaddress.sin_addr), R->hostname, R->hosttest,            
  10967.         R->sockfd);                                                             
  10968.                                                                                 
  10969.  /* This still doesn't do anything.                                             
  10970.   *                                                                             
  10971.   * if (hostentp && hostentp->h_name) {                                         
  10972.   *   memcpy(&R->clienthostent, hostentp, sizeof(struct hostent));              
  10973.   *   for (halias = R->clienthostent.h_aliases; *halias; halias++) {            
  10974.   *     printf("  Host alias:'%s'\n",*halias);                                  
  10975.   *   }                                                                         
  10976.   * }                                                                           
  10977.   */                                                                            
  10978.                                                                                 
  10979.  R->buffer[0] = '\0';                                                           
  10980.  bufptr = R->buffer;                                                            
  10981.                                                                                 
  10982. /***********************/                                                       
  10983. /*  NOTE:  sometimes, if timing is right, RECV can return a 0 length */         
  10984. /* record when a connection is closed by the client!!  below is a   */          
  10985. /* hack to check for a 0 length record, and then terminate this     */          
  10986. /* connection if we got one.                                        */          
  10987. /***********************/                                                       
  10988.                                                                                 
  10989. #define RECV_SIZE       (sizeof(R->buffer)-1)                                   
  10990.                                                                                 
  10991.  for (;;) {                                                                     
  10992.                                                                                 
  10993.    if (is_debug) {                                                              
  10994.      fprintf(stdout,"recv (sock=%d,size=%d)...\n",R->sockfd,RECV_SIZE);         
  10995.      fflush(stdout);                                                            
  10996.    }                                                                            
  10997.                                                                                 
  10998.    if ((len=recv(R->sockfd,outbuf,RECV_SIZE,0)) <= 0) {                         
  10999.      REPORT_TCP_ERROR("RECV - ");                                               
  11000.      printf("%s tcp error! len=%d\n",R->hostname, len);                         
  11001.      break;                                                                     
  11002.    }                                                                            
  11003.                                                                                 
  11004.    *(outbuf+(len))=0;    /*make sure it's null terminated...*/                  
  11005.    /* printf("len=%d;",len); */                                                 
  11006.    ASCII_TO_EBCDIC(outbuf,len);                                                 
  11007.    if (strlen(R->buffer) + strlen(outbuf) >= sizeof(R->buffer)) {               
  11008.      printf("\nError: More than %d bytes seen without CRLF\n",                  
  11009.             sizeof(R->buffer)-1);                                               
  11010.      len = 0;                                                                   
  11011.      break;                                                                     
  11012.    }                                                                            
  11013.    strcat(R->buffer,outbuf);                                                    
  11014.    bufptr=R->buffer+(strlen(R->buffer)-2);                                      
  11015.    if (*bufptr == CARRIAGE_RETURN && *(bufptr+1) == LINE_FEED) break;           
  11016.  }                                                                              
  11017.                                                                                 
  11018.  /* Note: no \n required, data line already has CRLF in it */                   
  11019.  fprintf(stderr,"%s %s Client data:%s",                                         
  11020.                 timestamp, R->hostname, R->buffer);                             
  11021.                                                                                 
  11022.  if (len < 0) return;                                                           
  11023.  else if (len == 0) {                                                           
  11024.    (void)GGMouts(R,                                                             
  11025.   "1Sorry, the GOPHER server couldn't hear you.  Try again.\t0\t0\t0");         
  11026.  }                                                                              
  11027.  else (void)GGMproc(R);                                                         
  11028.                                                                                 
  11029.  (void)GGMouts(R,NULL);          /* send terminating dot */                     
  11030.                                                                                 
  11031.  fflush(stdout);                                                                
  11032.  fflush(stderr);                                                                
  11033.                                                                                 
  11034. #ifdef DEBUGMTF                                                                 
  11035.  lookatsocket(R->sockfd);                                                       
  11036. #endif                                                                          
  11037.                                                                                 
  11038.  if (is_debug) {                                                                
  11039.    fprintf(stdout,"close (%d)...\n",R->sockfd);                                 
  11040.    fflush(stdout);                                                              
  11041.  }                                                                              
  11042.                                                                                 
  11043.  if(close(R->sockfd)<0) REPORT_TCP_ERROR("CLOSE - ");                           
  11044.                                                                                 
  11045. }                                                                               
  11046. ./ ENDUP                                                                        
  11047. ?!                                                                              
  11048. //CLIST    EXEC GGLOAD,TRK1='4',TO='CLIST'                                      
  11049. //SYSIN    DD DATA,DLM='?!'                                                     
  11050. ./   ADD NAME=GOPHER,SSI=01100012                                               
  11051. /* REXX. GOPHER client.  */                                                     
  11052.                                                                                 
  11053. /* *** Customize the following lines for your installation.                     
  11054.  * If ggmpanel is set to "", it will not be LIBDEF'd.                           
  11055.  */                                                                             
  11056.                                                                                 
  11057. ggmprefix      = "GOPHER"                                                       
  11058. ggmpanelsuffix = "PANELS"                                                       
  11059. ggmloadsuffix  = "LOAD"                                                         
  11060. ggmlmod        = "GGCLIENT"                                                     
  11061. ggmpanel       = ggmprefix"."ggmpanelsuffix                                     
  11062. ggmload        = ggmprefix"."ggmloadsuffix                                      
  11063. ggmappl        = ""                     /* ISPF applid (e.g. ISR)  */           
  11064. ggmdefaulthost = "gopher.micro.umn.edu" /* to initialize GOPHERRC  */           
  11065. gophermeister  = ""              /* TSOid of Gopher's Big Brother  */           
  11066. xprocavailable = 0               /* set to 1 if XPROC is available */           
  11067.                                                                                 
  11068. trace off                                                                       
  11069. signal on novalue                                                               
  11070. stacked   = 0                                                                   
  11071. libdeffed = 0                                                                   
  11072. parse arg args                                                                  
  11073. "ISPQRY"                                                                        
  11074. if rc > 0 then do                                                               
  11075.  parse source . . execname . execds .                                           
  11076.  if execds = "?" then                                                           
  11077.   icmd = "%"execname args                                                       
  11078.  else                                                                           
  11079.   icmd = "EX '"execds"("execname")'" quote(args)                                
  11080.  call startispf ggmappl, icmd                                                   
  11081.  exit                                                                           
  11082. end                                                                             
  11083.                                                                                 
  11084. if xprocavailable then do                                                       
  11085.                                                                                 
  11086.  save_prompt = prompt("ON")                                                     
  11087.  "XPROC 0 TEST DEBUG FORCE LOCAL                                                
  11088.           BOOKMARK() SERVER() PORT() PATH() DESCRIPTION()"                      
  11089.  if rc <> 0 then exit rc                                                        
  11090.  call prompt save_prompt                                                        
  11091.                                                                                 
  11092. end                                                                             
  11093.                                                                                 
  11094. else do /* XPROC not available */                                               
  11095.                                                                                 
  11096.  bookmark = ""                                                                  
  11097.  server = ""                                                                    
  11098.  port = 70                                                                      
  11099.  path  =                                                                        
  11100.  description =                                                                  
  11101.  local =                                                                        
  11102.  force =                                                                        
  11103.  test  =                                                                        
  11104.  debug =                                                                        
  11105.  uargs = translate(args)                                                        
  11106.  if wordpos("LOCAL",uargs) > 0 then local = "LOCAL"                             
  11107.  if wordpos("FORCE",uargs) > 0 then force = "FORCE"                             
  11108.  if wordpos("TEST" ,uargs) > 0 then test  = "TEST"                              
  11109.  if wordpos("DEBUG",uargs) > 0 then debug = "DEBUG"                             
  11110.                                                                                 
  11111. end                                                                             
  11112.                                                                                 
  11113. signal on failure                                                               
  11114. signal on halt                                                                  
  11115.                                                                                 
  11116. call check_for_other_socket_app                                                 
  11117. call read_gopherrc                                                              
  11118. call validate_operands                                                          
  11119. call libdef                                                                     
  11120. call let_me_know                                                                
  11121. call ggm_dialog                                                                 
  11122. call unlibdef                                                                   
  11123.                                                                                 
  11124. cleanup:                                                                        
  11125. if libdeffed then call unlibdef                                                 
  11126. if stacked then "DELSTACK"                                                      
  11127. exit                                                                            
  11128. error:failure:halt:say "GOPHER: Severe lossage."                                
  11129. say "Statement:" sourceline(sigl)                                               
  11130. exit                                                                            
  11131.                                                                                 
  11132. /*********************************************************************/         
  11133.                                                                                 
  11134. validate_operands:                                                              
  11135.                                                                                 
  11136. /*                                                                              
  11137.  * Logic that determines what to display on startup:                            
  11138.  * If gopherrc file does not exist, create it from default                      
  11139.  * (default has everything commented out except for a                           
  11140.  *  one-item "initial" menu pointing to the MVS server)                         
  11141.  * Read gopherrc (in case operands need fields therein)                         
  11142.  * Command operands override gopherrc specs:                                    
  11143.  * if LOCAL given then server = "-", see below for SERVER(-)                    
  11144.  * if SERVER(host) given then startup host=SERVER, path=PATH, etc.              
  11145.  *  (no gopherrc referenced)                                                    
  11146.  * if SERVER(-) given then either PATH must be given or                         
  11147.  *  the gopherrc's localmenu: must be given,                                    
  11148.  *  otherwise look at gopherrc                                                  
  11149.  *   if LOCAL given and initial: present then extract startup menu              
  11150.  *    but remember that there will be no server access possible                 
  11151.  *   else nothing given, this is an error, barf                                 
  11152.  * if no SERVER, look at gopherrc:                                              
  11153.  *   if initial: given then extract startup menu from there                     
  11154.  *   else if localmenu: given then use that menu (SERVER=-)                     
  11155.  *   else nothing given, display ISPF panel asking for host/path                
  11156.  */                                                                             
  11157.                                                                                 
  11158. if local = "LOCAL" then do                                                      
  11159.  if server <> "" then do                                                        
  11160.   say "GOPHER: SERVER cannot be specified when LOCAL is specified."             
  11161.   exit 12                                                                       
  11162.  end                                                                            
  11163.  server = "-"                                                                   
  11164. end                                                                             
  11165.                                                                                 
  11166. if bookmark <> "" then do                                                       
  11167.  if server <> "" & local = "" then do                                           
  11168.   say "GOPHER: SERVER cannot be specified when BOOKMARK is specified."          
  11169.   exit 12                                                                       
  11170.  end                                                                            
  11171.  if path <> "" then do                                                          
  11172.   say "GOPHER: PATH cannot be specified when BOOKMARK is specified."            
  11173.   exit 12                                                                       
  11174.  end                                                                            
  11175.  server = "-"                                                                   
  11176.  if left(bookmark,1) = "'" then path = strip(bookmark,"B","'")                  
  11177.  else do                                                                        
  11178.   tsoprefix = sysvar("SYSPREF")                                                 
  11179.   if tsoprefix = "" then path = bookmark                                        
  11180.   else path = tsoprefix"."bookmark                                              
  11181.  end                                                                            
  11182.  if description = "" then description = "Bookmark" path                         
  11183. end                                                                             
  11184.                                                                                 
  11185. ggpath = ""                                                                     
  11186. gghost = ""                                                                     
  11187. ggport = port                                                                   
  11188. ggdesc = description                                                            
  11189.                                                                                 
  11190. if server <> "" then do                                                         
  11191.  if server = "-" then do                                                        
  11192.   gghost = server                                                               
  11193.   if path <> "" then do                                                         
  11194.    ggpath = path                                                                
  11195.   end                                                                           
  11196.   else if localmenu <> "" then do                                               
  11197.    ggpath = localmenu                                                           
  11198.    if ggdesc = "" then ggdesc = "Local Private Gopher Menu"                     
  11199.   end                                                                           
  11200.   else if local = "LOCAL" & initial <> "" then do                               
  11201.    gghost = ""                                                                  
  11202.    call use_initial_spec                                                        
  11203.    if gghost <> "-" then do                                                     
  11204.     say "Gopher: Cannot determine path for local access."                       
  11205.     say "        Either specify PATH(pathname), activate"                       
  11206.     say "        the localmenu: line in GOPHERRC, or set"                       
  11207.     say "        the initial: line in GOPHERRC for local access."               
  11208.     exit 12                                                                     
  11209.    end                                                                          
  11210.   end                                                                           
  11211.   else do                                                                       
  11212.    say "Gopher: Cannot determine path for local access."                        
  11213.    say "        Either specify PATH(pathname) or activate"                      
  11214.    say "        the localmenu: or initial: line in GOPHERRC."                   
  11215.    exit 12                                                                      
  11216.   end                                                                           
  11217.  end                                                                            
  11218.  else do                                                                        
  11219.   gghost = server                                                               
  11220.   ggpath = path                                                                 
  11221.   ggdesc = description                                                          
  11222.   ggport = port                                                                 
  11223.   nop  /* use provided server, host, path, etc. */                              
  11224.  end                                                                            
  11225. end                                                                             
  11226. else do       /* no server given on command */                                  
  11227.  if localmenu <> "" then do                                                     
  11228.   gghost = "-"                                                                  
  11229.   ggpath = localmenu                                                            
  11230.   if ggdesc = "" then ggdesc = "Local Private Gopher Menu"                      
  11231.  end                                                                            
  11232.  else if initial <> "" then do                                                  
  11233.   call use_initial_spec                                                         
  11234.  end                                                                            
  11235.  else do                                                                        
  11236.   /* this is nominally illegal, but should cause gopher to                      
  11237.      display the hackish startup menu */                                        
  11238.   gghost = ""                                                                   
  11239.   ggpath = ""                                                                   
  11240.  end                                                                            
  11241. end                                                                             
  11242.                                                                                 
  11243. return                                                                          
  11244.                                                                                 
  11245. /*********************************************************************/         
  11246.                                                                                 
  11247. use_initial_spec:                                                               
  11248.                                                                                 
  11249.  if initial = "*temp*" then do                                                  
  11250.   /* we're eventually not going to do it this way really */                     
  11251.   /* initial_type is ignored - only "DIRECTORY" is valid anyway */              
  11252.   if initial_name <> "" & ggdesc = "" then ggdesc = initial_name                
  11253.   if initial_host <> "" & gghost = "" then gghost = initial_host                
  11254.   if initial_path <> "" & ggpath = "" then ggpath = initial_path                
  11255.   if initial_port <> "" & ggport = "" then ggport = initial_port                
  11256.  end                                                                            
  11257.  else do                                                                        
  11258.   ggpath = initial                                                              
  11259.   if ggdesc = "" then ggdesc = "Local Private Gopher Menu"                      
  11260.  end                                                                            
  11261.                                                                                 
  11262. return                                                                          
  11263.                                                                                 
  11264. /*********************************************************************/         
  11265.                                                                                 
  11266. read_gopherrc:                                                                  
  11267.                                                                                 
  11268. localmenu = ""                                                                  
  11269. localexec = ""                                                                  
  11270. initial   = ""                                                                  
  11271. initial_type = ""                                                               
  11272. initial_name = ""                                                               
  11273. initial_host = ""                                                               
  11274. initial_path = ""                                                               
  11275. initial_port = ""                                                               
  11276. new_gopherrc = 0                                                                
  11277. gopherrc = "'"userid()".GOPHERRC'"                                              
  11278. gopherdcb = "RECFM(V B) LRECL(255) BLKSIZE(6233) DSORG(PS)"                     
  11279. gopherrc_status = sysdsn(gopherrc)                                              
  11280. select                                                                          
  11281.  when gopherrc_status = "OK" then nop                                           
  11282.  when gopherrc_status = "DATASET NOT FOUND" then do                             
  11283.   address TSO "ALLOC DA("gopherrc") T SP(1 1)" gopherdcb                        
  11284.   if rc <> 0 then do                                                            
  11285.    say "Error: Cannot create" gopherrc                                          
  11286.    exit rc                                                                      
  11287.   end                                                                           
  11288.   new_gopherrc = 1                                                              
  11289.  end                                                                            
  11290.  otherwise do                                                                   
  11291.   say "Error: Cannot access" gopherrc":" gopherrc_status                        
  11292.   exit 16                                                                       
  11293.  end                                                                            
  11294. end                                                                             
  11295.                                                                                 
  11296. address TSO "ALLOC FI(GOPHERRC) DA("gopherrc") OLD REU"                         
  11297. if rc <> 0 then exit rc                                                         
  11298.                                                                                 
  11299. if new_gopherrc = 0 then do                                                     
  11300.  "EXECIO * DISKR GOPHERRC (FINIS STEM GOPHERRC.)"                               
  11301.  execiorc = rc                                                                  
  11302.  if execiorc <> 0 then do                                                       
  11303.   say "Error: Cannot read" gopherrc                                             
  11304.   address TSO "FREE FI(GOPHERRC)"                                               
  11305.   exit execiorc                                                                 
  11306.  end                                                                            
  11307.  if gopherrc.0 = 0 then new_gopherrc = 1                                        
  11308. end                                                                             
  11309.                                                                                 
  11310. if new_gopherrc then call initialize_gopherrc                                   
  11311.                                                                                 
  11312. address TSO "FREE FI(GOPHERRC)"                                                 
  11313.                                                                                 
  11314. collecting_initial = 0                                                          
  11315. do i = 1 to gopherrc.0                                                          
  11316.  gline = gopherrc.i                                                             
  11317.  if gline = "" then iterate                                                     
  11318.  if left(gline,1) = '#' then iterate                                            
  11319.  parse var gline ghead ":" gtext                                                
  11320.  ghead = translate(strip(ghead,"B"))                                            
  11321.  gtext = strip(gtext,"B")                                                       
  11322.  if collecting_initial then do                                                  
  11323.   parse var gline ghead "=" gtext                                               
  11324.   ghead = translate(strip(ghead,"B"))                                           
  11325.   gtext = strip(gtext,"B")                                                      
  11326.   select                                                                        
  11327.    when ghead = "TYPE" then initial_type = gtext                                
  11328.    when ghead = "NAME" then initial_name = gtext                                
  11329.    when ghead = "PATH" then initial_path = gtext                                
  11330.    when ghead = "HOST" then initial_host = gtext                                
  11331.    when ghead = "PORT" then initial_port = gtext                                
  11332.    when ghead = "END"  then do                                                  
  11333.     collecting_initial = 0                                                      
  11334.     initial = "*temp*"                                                          
  11335.    end                                                                          
  11336.    otherwise do                                                                 
  11337.     say "Error in "gopherrc": INITIAL: not terminated by END"                   
  11338.     say "Line where error was detected:"                                        
  11339.     say gline                                                                   
  11340.     exit 8                                                                      
  11341.    end                                                                          
  11342.   end                                                                           
  11343.  end                                                                            
  11344.  else select                                                                    
  11345.   when ghead = "LOCALMENU" then localmenu = gtext                               
  11346.   when ghead = "LOCALEXEC" then localexec = gtext                               
  11347.   when ghead = "INITIAL"   then do                                              
  11348.    if gtext = "" then collecting_initial = 1                                    
  11349.    else initial = gtext                                                         
  11350.   end                                                                           
  11351.   otherwise do                                                                  
  11352.    say "Warning, gopherrc field ignored:" ghead                                 
  11353.   end                                                                           
  11354.  end                                                                            
  11355. end                                                                             
  11356.                                                                                 
  11357. return                                                                          
  11358.                                                                                 
  11359. /*********************************************************************/         
  11360.                                                                                 
  11361. ggm_dialog:                                                                     
  11362.                                                                                 
  11363. vputvars = "GGHOST GGPORT GGPATH GGDESC"                                        
  11364.                                                                                 
  11365. if vputvars <> "" then do                                                       
  11366.  address ISPEXEC "VPUT ("vputvars") PROFILE"                                    
  11367.  if rc <> 0 then do; call ispf_error rc; exit rc; end                           
  11368. end                                                                             
  11369.                                                                                 
  11370. parm = ""                                                                       
  11371. if test  = "TEST"  then parm = parm "-t"                                        
  11372. if debug = "DEBUG" then parm = parm "-d"                                        
  11373. if local = "LOCAL" then parm = parm "-l"                                        
  11374. if gghost <> ""    then parm = parm "-q"                                        
  11375.                                                                                 
  11376. zerrmsg = ""                                                                    
  11377. zerrsm  = ""                                                                    
  11378. zerrlm  = ""                                                                    
  11379.                                                                                 
  11380. if ggmappl = "" then applsource = ""                                            
  11381. else applsource = "NEWAPPL("ggmappl") PASSLIB"                                  
  11382.                                                                                 
  11383. if ggmload = "" then selstring = "PGM("ggmlmod") PARM("parm")"                  
  11384. else selstring = "CMD(CALL '"ggmload"("ggmlmod")'" quote(parm)")"               
  11385.                                                                                 
  11386. address ISPEXEC "SELECT" applsource selstring                                   
  11387.                                                                                 
  11388. if rc <> 0 then say "Return code from" ggmlmod "program is" rc                  
  11389.                                                                                 
  11390. address ISPEXEC "VGET (ZERRSM ZERRLM)"                                          
  11391. if zerrsm <> "" then do                                                         
  11392.  say zerrmsg":" zerrsm                                                          
  11393.  say zerrlm                                                                     
  11394. end                                                                             
  11395.                                                                                 
  11396. return                                                                          
  11397.                                                                                 
  11398. /*********************************************************************/         
  11399.                                                                                 
  11400. libdef:                                                                         
  11401. if ggmpanel <> "" then do                                                       
  11402.  address ISPEXEC "LIBDEF ISPPLIB DATASET ID('"ggmpanel"')"                      
  11403.  if rc <> 0 then do; call ispf_error rc; exit rc; end                           
  11404. end                                                                             
  11405. if localexec <> "" then do                                                      
  11406.  address TSO "ALLOC FI(GGEXEC) SHR REU DA('"localexec"')"                       
  11407.  if rc <> 0 then exit rc                                                        
  11408. end                                                                             
  11409. libdeffed = 1                                                                   
  11410. return                                                                          
  11411.                                                                                 
  11412. /*********************************************************************/         
  11413.                                                                                 
  11414. unlibdef:                                                                       
  11415. if localexec <> "" then do                                                      
  11416.  address TSO "FREE FI(GGEXEC)"                                                  
  11417. end                                                                             
  11418. if ggmpanel <> "" then do                                                       
  11419.  address ISPEXEC "LIBDEF ISPPLIB DATASET"                                       
  11420.  if rc <> 0 then call ispf_error rc                                             
  11421. end                                                                             
  11422. libdeffed = 0                                                                   
  11423. return                                                                          
  11424.                                                                                 
  11425. /*********************************************************************/         
  11426.                                                                                 
  11427. initialize_gopherrc:                                                            
  11428.                                                                                 
  11429.  say "Initializing new GOPHERRC file..."                                        
  11430.  do i = sigl while sourceline(i) <> "_BEGIN_"                                   
  11431.  end                                                                            
  11432.  gx = 0                                                                         
  11433.  do i = i+1 by 1                                                                
  11434.   gline = sourceline(i)                                                         
  11435.   if gline = "_END_" then leave                                                 
  11436.   gpos = pos("ggmdefaulthost",gline)                                            
  11437.   if gpos > 0 then do                                                           
  11438.    gline = substr(gline,1,gpos-1) || ggmdefaulthost                             
  11439.   end                                                                           
  11440.   gx = gx + 1                                                                   
  11441.   gopherrc.gx = gline                                                           
  11442.  end                                                                            
  11443.  gopherrc.0 = gx                                                                
  11444.  "EXECIO * DISKW GOPHERRC (FINIS STEM GOPHERRC.)"                               
  11445.  say "New GOPHERRC file initialized."                                           
  11446.                                                                                 
  11447. return                                                                          
  11448.                                                                                 
  11449. /*                                                                              
  11450.                                                                                 
  11451. _BEGIN_                                                                         
  11452. #                                                                               
  11453. #                                                                               
  11454. # Default "gopherrc" file, created by the MVS Gopher client.                    
  11455. #                                                                               
  11456. # Uncomment desired fields by removing the initial "# " from them.              
  11457. #                                                                               
  11458. # Beware - the Gopher client may update this file with bookmarks.               
  11459. #          You can delete it at any time and it will be recreated               
  11460. #          from the default settings, but you'll lose your bookmarks.           
  11461. #                                                                               
  11462. ######################################################################          
  11463. #                                                                               
  11464. # If you want local (serverless) gopher access, then use the following          
  11465. # lines, specifying full qualified (no quotes) data set names:                  
  11466. #                                                                               
  11467. # localmenu: name_of_initial_gopher_menu                                        
  11468. # localexec: name_of_pds_of_rexx_execs                                          
  11469. #                                                                               
  11470. # Specifying localmenu: is equivalent to specifying an initial: section         
  11471. # with host set to "-" and path set to the value of localmenu.                  
  11472. #                                                                               
  11473. # You cannot use your own REXX execs, however, unless you specify               
  11474. # localexec: as above.  You don't need one to use the other, though.            
  11475. #                                                                               
  11476. ######################################################################          
  11477. #                                                                               
  11478. # The following is used by the Gopher client at startup to determine            
  11479. # how the initial menu will appear.                                             
  11480. #                                                                               
  11481. # You may want to change the host to the one appropriate for your site.         
  11482. #                                                                               
  11483. initial:                                                                        
  11484. #                                                                               
  11485. Type=DIRECTORY                                                                  
  11486. Name=Primary (Root) Gopher Menu                                                 
  11487. Path=                                                                           
  11488. Host=ggmdefaulthost                                                             
  11489. Port=70                                                                         
  11490. End                                                                             
  11491. #                                                                               
  11492. # Alternatively, if you want your own private Gopher data:                      
  11493. #                                                                               
  11494. # initial:                                                                      
  11495. #                                                                               
  11496. # Type=0                                                                        
  11497. # Name=My Own Private Gopherhole                                                
  11498. # Path=userid.GOPHER.MENU                                                       
  11499. # Host=-                                                                        
  11500. # End                                                                           
  11501. #                                                                               
  11502. # In which case you should create a data set called userid.GOPHER.MENU          
  11503. # (or whatever name you choose that appears in the "Path=" line above)          
  11504. # that looks like this.  (NOT in the gopherrc file!)                            
  11505. #                                                                               
  11506. #                                                                               
  11507. # gopher_menu                                                                   
  11508. #                                                                               
  11509. # TYPE=DIRECTORY                                                                
  11510. # NAME=Public GOPHER Server at ggmdefaulthost                                   
  11511. # PATH=                                                                         
  11512. # HOST=ggmdefaulthost                                                           
  11513. # END                                                                           
  11514. #                                                                               
  11515. # TYPE=DIRECTORY                                                                
  11516. # NAME=Private GOPHER                                                           
  11517. # PATH=userid.ANOTHER.GOPHER.MENU                                               
  11518. # HOST=-                                                                        
  11519. # END                                                                           
  11520. #                                                                               
  11521. # and then you need yet another menu, similar in format to this one,            
  11522. # in userid.ANOTHER.GOPHER.MENU.  Get the idea?                                 
  11523. #                                                                               
  11524. ######################################################################          
  11525. #                                                                               
  11526. # These fields may be used by the Gopher client for local purposes              
  11527. # in the future.  Currently they are ignored.                                   
  11528. #                                                                               
  11529. # Printercmd: lpr                                                               
  11530. # Telnetcmd: telnet                                                             
  11531. # Mailcmd: mail                                                                 
  11532. # Playcmd: play -v 40 -                                                         
  11533. # TN3270cmd: tn3270                                                             
  11534. # MIMEcmd: metamail -p                                                          
  11535. #                                                                               
  11536. ######################################################################          
  11537. _END_                                                                           
  11538.                                                                                 
  11539. */                                                                              
  11540.                                                                                 
  11541. /*********************************************************************/         
  11542.                                                                                 
  11543. check_for_other_socket_app:                                                     
  11544.                                                                                 
  11545.  if local = "LOCAL" then return                                                 
  11546.                                                                                 
  11547.  call nnmfiucv      /* FIND IUCVMULT in another PIE MultiTSO session */         
  11548.                                                                                 
  11549.  if result = 0 then return                                                      
  11550.                                                                                 
  11551.  say,                                                                           
  11552.  "A TCP/IP socket application appears active in another PIE session."           
  11553.  if force = "FORCE" then do                                                     
  11554.   say "Proceeding anyhow, because you said FORCE."                              
  11555.   return                                                                        
  11556.  end                                                                            
  11557.  say "To proceed at this point would be potentially disastrous."                
  11558.  say "If you want to use GOPHER anyway, use one of these operands:"             
  11559.  say "  FORCE  -  if I'm mistaken and it's really safe to make a"               
  11560.  say "            TCP/IP connection."                                           
  11561.  say "  LOCAL  -  if you just want local (serverless) access."                  
  11562.  say "Terminating."                                                             
  11563.                                                                                 
  11564. exit 16                                                                         
  11565.                                                                                 
  11566. /*********************************************************************/         
  11567.                                                                                 
  11568. ispf_error: parse arg ispfrc                                                    
  11569.                                                                                 
  11570. say "GOPHER: ISPF dialog service error detected on line" sigl                   
  11571. say sourceline(sigl)                                                            
  11572. say                                                                             
  11573. say zerrmsg":" zerrsm                                                           
  11574. say zerrlm                                                                      
  11575. say                                                                             
  11576.                                                                                 
  11577. return ispfrc                                                                   
  11578.                                                                                 
  11579. /*********************************************************************/         
  11580.                                                                                 
  11581. /*                                                                              
  11582.  * The following function starts ISPF from READY mode.                          
  11583.  * Beware:  splitting the screen starts up an identical copy of the             
  11584.  *          application, which may not be desirable.                            
  11585.  */                                                                             
  11586.                                                                                 
  11587. startispf: parse arg startappl, startcmd                                        
  11588. if startappl = "" then,                                                         
  11589.  "ISPSTART CMD("startcmd")"                                                     
  11590. else,                                                                           
  11591.  "ISPSTART NEWAPPL("startappl") CMD("startcmd")"                                
  11592. return                                                                          
  11593.                                                                                 
  11594. /* The following function implements Big Brother mode. */                       
  11595.                                                                                 
  11596. let_me_know:                                                                    
  11597. if gophermeister = "" | gophermeister = userid() then return                    
  11598. parse source . . execname . execds .                                            
  11599. call outtrap "X."                                                               
  11600. address TSO,                                                                    
  11601.  "SEND" quote(execds"("execname")" date("U") time()" "),                        
  11602.         "U("gophermeister") LOGON"                                              
  11603. call outtrap "OFF"                                                              
  11604. return                                                                          
  11605.                                                                                 
  11606. /* The following function enquotes a string. */                                 
  11607.                                                                                 
  11608. quote: parse arg string                                                         
  11609. ix = 1                                                                          
  11610. do forever                                                                      
  11611.  ix = pos("'",string,ix)                                                        
  11612.  if ix = 0 then return "'"string"'"                                             
  11613.  string = insert("'",string,ix)                                                 
  11614.  ix=ix+2                                                                        
  11615. end                                                                             
  11616.                                                                                 
  11617. ./   ADD NAME=HOSTNAME,SSI=01000048                                             
  11618. /* REXX */                                                                      
  11619.                                                                                 
  11620. return "MVS.DRAPER.COM"   /* or your hostname, in production */                 
  11621. /* return "-" */          /* for local private testing */                       
  11622.                                                                                 
  11623. ./   ADD NAME=NNMFIUCV,SSI=01000017                                             
  11624. /* REXX.  This exec scans the job pack queues for IUCVMULT and returns          
  11625.  * with an error code if IUCVMULT is already loaded under a                     
  11626.  * different TCB. This can only happen under PIE MultiTSO or a                  
  11627.  * similar product that makes multiple job step TCB's.                          
  11628.  */                                                                             
  11629.                                                                                 
  11630. trace off                                                                       
  11631. signal on novalue                                                               
  11632.                                                                                 
  11633. search_name = "IUCVMULT"                                                        
  11634. count = 0                                                                       
  11635. foundtcb. = ""                                                                  
  11636. current_tcb  = getword24("21C")                                                 
  11637. current_job_step_tcb = getword24(current_tcb,"7C")                              
  11638. current_ascb = getword24("224")                                                 
  11639. current_asxb = getword31(current_ascb,"6C")                                     
  11640. first_tcb    = getword24(current_asxb,"4")                                      
  11641. tcb = first_tcb                                                                 
  11642. motherflag = 0                                                                  
  11643. do forever                                                                      
  11644.  if motherflag = 0 then do                                                      
  11645.   call process                                                                  
  11646.   daughter_tcb = getword24(tcb,"88")                                            
  11647.   if daughter_tcb \= "00000000" then do                                         
  11648.    tcb = daughter_tcb                                                           
  11649.    iterate                                                                      
  11650.   end                                                                           
  11651.  end                                                                            
  11652.  motherflag = 0                                                                 
  11653.  sister_tcb = getword24(tcb, "80")                                              
  11654.  if sister_tcb \= "00000000" then do                                            
  11655.   tcb = sister_tcb                                                              
  11656.   iterate                                                                       
  11657.  end                                                                            
  11658.  mother_tcb = getword24(tcb, "84")                                              
  11659.  if mother_tcb \= "00000000" then do                                            
  11660.   tcb = mother_tcb                                                              
  11661.   motherflag = 1                                                                
  11662.   iterate                                                                       
  11663.  end                                                                            
  11664.  leave                                                                          
  11665. end                                                                             
  11666.                                                                                 
  11667. if count = 0 then return 0                                                      
  11668. problem = 0                                                                     
  11669. do i = 1 to count                                                               
  11670.  if foundtcb.i = current_job_step_tcb then do                                   
  11671.   /*                                                                            
  11672.   say search_name "is already loaded under current TCB at "foundtcb.i"."        
  11673.   */                                                                            
  11674.  end                                                                            
  11675.  else do                                                                        
  11676.   /*                                                                            
  11677.   say search_name "is loaded under different TCB at "foundtcb.i"."              
  11678.   */                                                                            
  11679.   problem = 1                                                                   
  11680.  end                                                                            
  11681. end                                                                             
  11682.                                                                                 
  11683. if problem = 1 then return 1                                                    
  11684.                                                                                 
  11685. else return 0                                                                   
  11686.                                                                                 
  11687. process:                                                                        
  11688.                                                                                 
  11689.  jpq = getword31(tcb,"2C")                                                      
  11690.  cde = jpq                                                                      
  11691.  do while cde \= "00000000"                                                     
  11692.   cde_contents = storage(cde,32)                                                
  11693.   cde_name = substr(cde_contents,9,8)                                           
  11694.   cde_epa  = substr(cde_contents,9,8)                                           
  11695.   if search_name = cde_name then do                                             
  11696.    count = count + 1                                                            
  11697.    foundtcb.count = tcb                                                         
  11698.   end                                                                           
  11699.   cde = getword31(cde,"0")                                                      
  11700.  end                                                                            
  11701.                                                                                 
  11702. return                                                                          
  11703.                                                                                 
  11704. getword31: parse arg addr, offset                                               
  11705. temp1 = x2d(addr)                                                               
  11706. if offset = "" then temp2 = 0                                                   
  11707. else temp2 = x2d(offset)                                                        
  11708. return c2x(storage(d2x(temp1+temp2),4))                                         
  11709.                                                                                 
  11710. getword24: parse arg addr, offset                                               
  11711. temp1 = x2d(addr)                                                               
  11712. if offset = "" then temp2 = 0                                                   
  11713. else temp2 = x2d(offset)                                                        
  11714. return "00"c2x(storage(d2x(temp1+temp2+1),3))                                   
  11715.                                                                                 
  11716. ./   ADD NAME=TSOHELP,SSI=01020035                                              
  11717. /* REXX */                                                                      
  11718.                                                                                 
  11719. /* This exec provides a sample TSO HELP application.                            
  11720.    The gopher menu item will look something like this:                          
  11721.                                                                                 
  11722. TYPE=DIRECTORY                                                                  
  11723. NAME=TSO HELP                                                                   
  11724. PATH=EXEC:TSOHELP                                                               
  11725. HOST=+                                                                          
  11726. END                                                                             
  11727.                                                                                 
  11728. where "TSOHELP" is the name of this exec.                                       
  11729.                                                                                 
  11730. This exec generates a series of lower-level menus, giving the user              
  11731. a choice of how much help data to search (IBM only, local installation          
  11732. help, etc.).  This particular sample is Draper Lab's own, so you will           
  11733. need to change it.                                                              
  11734.                                                                                 
  11735.  */                                                                             
  11736.                                                                                 
  11737. trace off                                                                       
  11738. signal on novalue                                                               
  11739.                                                                                 
  11740. host = hostname()                                                               
  11741. port = "70"                                                                     
  11742. tab  = '05'x                                                                    
  11743.                                                                                 
  11744. helpfiles.        = "'SYS1.HELP'"                                               
  11745. helpfiles.sys1    = "'SYS1.HELP'"                                               
  11746. helpfiles.draper  = "'CSD.CMD.HELP' 'CSD.PP.HELP' 'SYS1.HELP'"                  
  11747. helpfiles.proglib = "'PROGLIB.CMD.HELP'"                                        
  11748.                                                                                 
  11749. parse arg helplib command type extra                                            
  11750.                                                                                 
  11751. if helplib = "" then,                                                           
  11752.      call display_top_menus                                                     
  11753. else call set_up_help helplib,command,type,extra                                
  11754.                                                                                 
  11755. return 0                                                                        
  11756.                                                                                 
  11757. /*------------------------------------------------------------------*/          
  11758.                                                                                 
  11759. display_top_menus:                                                              
  11760.                                                                                 
  11761.  call start_output                                                              
  11762.  call menu_out "SYS1",  "COMMANDS","DIRECTORY","Regular IBM TSO Help"           
  11763.  call menu_out "DRAPER","COMMANDS","DIRECTORY","IBM and Draper TSO Help"        
  11764.  call menu_out "PROGLIB","PROGLIB" ,"DIRECTORY","PROGLIB TSO Help"              
  11765.  call end_output                                                                
  11766.                                                                                 
  11767. return                                                                          
  11768.                                                                                 
  11769. /*------------------------------------------------------------------*/          
  11770.                                                                                 
  11771. set_up_help:  parse arg helplib,command,type,extra                              
  11772.                                                                                 
  11773.  call outtrap "TSO."                                                            
  11774.  "ALLOC FI(SYSHELP) SHR REU DA("helpfiles.helplib")"                            
  11775.  allocrc = rc                                                                   
  11776.  call outtrap "OFF"                                                             
  11777.  if allocrc <> 0 then do                                                        
  11778.   call start_output                                                             
  11779.   do i = 1 to tso.0                                                             
  11780.    call menu_out "ERROR","ERROR","DIRECTORY",tso.i                              
  11781.   end                                                                           
  11782.   call end_output                                                               
  11783.  end                                                                            
  11784.  else do                                                                        
  11785.   select                                                                        
  11786.    when type = "FILE"      then call specific_help command,extra                
  11787.    when type = "DIRECTORY" then call general_help  command,extra                
  11788.    when type = "INDEX"     then call index_help    extra                        
  11789.    otherwise                    call specific_help command                      
  11790.  end                                                                            
  11791.                                                                                 
  11792. return                                                                          
  11793.                                                                                 
  11794. /*------------------------------------------------------------------*/          
  11795.                                                                                 
  11796. index_help:                                                                     
  11797.                                                                                 
  11798.  /* This intermediate one-element directory is necessary because                
  11799.   * the Gopher INDEX format only returns directories, not files.                
  11800.   */                                                                            
  11801.                                                                                 
  11802.  parse upper arg commands                                                       
  11803.  call start_output                                                              
  11804.  do while commands <> ""                                                        
  11805.   parse var commands command commands                                           
  11806.   call menu_out helplib,command,"FILE","Complete help for" command              
  11807.   call menu_out helplib,command,"FILE","Function help only","FUNCTION"          
  11808.   call menu_out helplib,command,"FILE","Syntax help only","SYNTAX"              
  11809.   call menu_out helplib,command,"FILE","Operands help only","OPERANDS"          
  11810.  end                                                                            
  11811.  call end_output                                                                
  11812.                                                                                 
  11813. return                                                                          
  11814.                                                                                 
  11815. /*------------------------------------------------------------------*/          
  11816.                                                                                 
  11817. general_help:                                                                   
  11818.                                                                                 
  11819. parse arg command,extra                                                         
  11820.                                                                                 
  11821. call get_help_text command,extra                                                
  11822.                                                                                 
  11823. call start_output                                                               
  11824.                                                                                 
  11825. call menu_out helplib,"*","INDEX","Help for a specific TSO command"             
  11826.                                                                                 
  11827. do i = 1 to help.0                                                              
  11828.  parse var help.i helpname helpdesc                                             
  11829.  if helpdesc <> "" & ,                                                          
  11830.     length(helpname) <= 8 & ,                                                   
  11831.     helpname < "0" & ,                                                          
  11832.     verify(helpname,"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789W#$") = 0 ,            
  11833.     then do                                                                     
  11834.                                                                                 
  11835.   /*                                                                            
  11836.    * Draper help has a series of "$..." members which are like                  
  11837.    * sublevel COMMANDS members.  This hack supports that.                       
  11838.    */                                                                           
  11839.                                                                                 
  11840.   if left(helpname,1) = "$" then do                                             
  11841.    call menu_out helplib,helpname,"DIRECTORY",helpdesc                          
  11842.   end                                                                           
  11843.   else do                                                                       
  11844.    call menu_out helplib,helpname,"FILE",helpdesc                               
  11845.   end                                                                           
  11846.  end                                                                            
  11847. end                                                                             
  11848.                                                                                 
  11849. call end_output                                                                 
  11850.                                                                                 
  11851. return                                                                          
  11852.                                                                                 
  11853. /*------------------------------------------------------------------*/          
  11854.                                                                                 
  11855. specific_help:                                                                  
  11856.                                                                                 
  11857. parse arg command,extra                                                         
  11858.                                                                                 
  11859. call get_help_text command,extra                                                
  11860.                                                                                 
  11861. call start_output                                                               
  11862.                                                                                 
  11863. do i = 1 to help.0                                                              
  11864.  call text_output help.i                                                        
  11865. end                                                                             
  11866.                                                                                 
  11867. call end_output                                                                 
  11868.                                                                                 
  11869. return                                                                          
  11870.                                                                                 
  11871. /*------------------------------------------------------------------*/          
  11872.                                                                                 
  11873. get_help_text:                                                                  
  11874.                                                                                 
  11875. parse arg helpcmd,helpargs                                                      
  11876.                                                                                 
  11877. help. =                                                                         
  11878.                                                                                 
  11879. call outtrap "HELP."                                                            
  11880.                                                                                 
  11881. address TSO "HELP" helpcmd helpargs                                             
  11882.                                                                                 
  11883. call outtrap "OFF"                                                              
  11884.                                                                                 
  11885. return                                                                          
  11886.                                                                                 
  11887. /*------------------------------------------------------------------*/          
  11888.                                                                                 
  11889. menu_out: parse arg mlib,mname,mtype,mdesc,mops                                 
  11890.                                                                                 
  11891.  select                                                                         
  11892.   when mtype = "FILE"      then gtype = "0"                                     
  11893.   when mtype = "DIRECTORY" then gtype = "1"                                     
  11894.   when mtype = "INDEX"     then gtype = "7"                                     
  11895.   otherwise do                                                                  
  11896.    call menu_out "ERROR","ERROR","DIRECTORY", "Unknown type:" mtype             
  11897.   end                                                                           
  11898.  end                                                                            
  11899.                                                                                 
  11900.  gname = left(mname,9)"--" mdesc                                                
  11901.  gpath = "EXEC:TSOHELP" mlib mname mtype mops                                   
  11902.  out = gtype || gname || tab || gpath || tab || host || tab || port             
  11903.  queue out                                                                      
  11904.                                                                                 
  11905. return                                                                          
  11906.                                                                                 
  11907. /*------------------------------------------------------------------*/          
  11908.                                                                                 
  11909. text_output: parse arg text                                                     
  11910.                                                                                 
  11911.  if text = "" then queue " "                                                    
  11912.  else queue text                                                                
  11913.                                                                                 
  11914. return                                                                          
  11915.                                                                                 
  11916. /*------------------------------------------------------------------*/          
  11917.                                                                                 
  11918. start_output:                                                                   
  11919.                                                                                 
  11920. "newstack"                                                                      
  11921.                                                                                 
  11922. return                                                                          
  11923.                                                                                 
  11924. /*------------------------------------------------------------------*/          
  11925.                                                                                 
  11926. end_output:                                                                     
  11927.                                                                                 
  11928. queue ""                                                                        
  11929.                                                                                 
  11930. "EXECIO * DISKW SYSTSPRT (FINIS)"                                               
  11931.                                                                                 
  11932. "delstack"                                                                      
  11933.                                                                                 
  11934. return                                                                          
  11935.                                                                                 
  11936. ./ ENDUP                                                                        
  11937. ?!                                                                              
  11938. //H        EXEC GGLOAD,TRK1='4',TO='H'                                          
  11939. //SYSIN    DD DATA,DLM='?!'                                                     
  11940. ./   ADD NAME=GG,SSI=01180014                                                   
  11941.                                                                                 
  11942.  /********************************************************************/         
  11943.  /*                                                                  */         
  11944.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  11945.  /*                                                                  */         
  11946.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  11947.  /*                                                                  */         
  11948.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  11949.  /* including the implied warranties of merchantability and fitness, */         
  11950.  /* are expressly denied.                                            */         
  11951.  /*                                                                  */         
  11952.  /* Provided this copyright notice is included, this software may    */         
  11953.  /* be freely distributed and not offered for sale.                  */         
  11954.  /*                                                                  */         
  11955.  /* Changes or modifications may be made and used only by the maker  */         
  11956.  /* of same, and not further distributed.  Such modifications should */         
  11957.  /* be mailed to the author for consideration for addition to the    */         
  11958.  /* software and incorporation in subsequent releases.               */         
  11959.  /*                                                                  */         
  11960.  /********************************************************************/         
  11961.                                                                                 
  11962. /* --------------------- "gg.h" include member --------------------- */         
  11963.                                                                                 
  11964. #pragma linkage(ispexec,OS)                                                     
  11965. #pragma linkage(isplink,OS)                                                     
  11966. #pragma linkage(ikjeff18,OS)                                                    
  11967.                                                                                 
  11968. /****** Installation-customized defines. *****************************/         
  11969.                                                                                 
  11970. #include "gguser.h"                                                             
  11971.                                                                                 
  11972. #ifndef  C370V1                                                                 
  11973. #ifndef  C370V2                                                                 
  11974. #ifndef  SASC                                                                   
  11975.  install_error_neither_C370V1_C370V2_nor_SASC_was_defined;                      
  11976. #endif                                                                          
  11977. #endif                                                                          
  11978. #endif                                                                          
  11979.                                                                                 
  11980. #ifndef  TCPIPV1                                                                
  11981. #ifndef  TCPIPV2                                                                
  11982. #ifndef  SNSTCPIP                                                               
  11983.  install_error_neither_TCPIPV1_TCPIPV2_nor_SNSTCPIP_was_defined;                
  11984. #endif                                                                          
  11985. #endif                                                                          
  11986. #endif                                                                          
  11987.                                                                                 
  11988. #ifndef  ISPFV2                                                                 
  11989. #ifndef  ISPFV3                                                                 
  11990.  install_error_neither_ISPFV2_nor_ISPFV3_was_defined;                           
  11991. #endif                                                                          
  11992. #endif                                                                          
  11993.                                                                                 
  11994. #define  MVS                                                                    
  11995.                                                                                 
  11996. /****** Clean up compiler warnings BEFORE time.h gets 'em ************/         
  11997.                                                                                 
  11998. #ifndef  SASC                                                                   
  11999. #define  localtime            LOCALTIM                                          
  12000. #endif                                                                          
  12001.                                                                                 
  12002. /****** Include all header files that are necessary. *****************/         
  12003.                                                                                 
  12004. #ifndef SNSTCPIP                                                                
  12005. #include <manifest.h>                                                           
  12006. #include <sys/types.h>                                                          
  12007. #include <netinet/in.h>                                                         
  12008. #include <sys/ioctl.h>                                                          
  12009. #include <tcperrno.h>                                                           
  12010. #include <fcntl.h>                                                              
  12011. #endif                                                                          
  12012.                                                                                 
  12013. #include <sys/socket.h>                                                         
  12014. #include <netdb.h>                                                              
  12015. #include <sys/uio.h>                                                            
  12016. #include <ctype.h>                                                              
  12017. #include <errno.h>                                                              
  12018. #include <limits.h>                                                             
  12019. #include <setjmp.h>                                                             
  12020. #include <stdio.h>                                                              
  12021. #include <stdarg.h>                                                             
  12022. #include <stdlib.h>                                                             
  12023. #include <string.h>                                                             
  12024. #include <stddef.h>                                                             
  12025. #include <time.h>                                                               
  12026.                                                                                 
  12027. #ifdef SNSTCPIP                                                                 
  12028. #include <acs.h>                                                                
  12029. #include <inet.h>                                                               
  12030. #include <sockcfg.h>                                                            
  12031. #include <serrno.h>                                                             
  12032. #endif                                                                          
  12033.                                                                                 
  12034. #ifndef  SASC                                                                   
  12035. #include <ctest.h>                                                              
  12036. #endif                                                                          
  12037.                                                                                 
  12038. #ifdef   SASC                                                                   
  12039. #include "ggsasc.h"                                                             
  12040. #endif                                                                          
  12041.                                                                                 
  12042. #undef ENOMEM                                                                   
  12043.                                                                                 
  12044. #include <mtf.h>                                                                
  12045.                                                                                 
  12046. /****** Version-dependent stuff **************************************/         
  12047.                                                                                 
  12048. #ifdef   C370V1                                                                 
  12049. #undef   FETCH                                                                  
  12050. #endif                                                                          
  12051.                                                                                 
  12052. #ifdef   C370V2                                                                 
  12053. #define  FETCH                                                                  
  12054. #endif                                                                          
  12055.                                                                                 
  12056. #ifdef   TCPIPV1                                                                
  12057. #define  TCP_DEBUG            tcp_debug                                         
  12058. #endif                                                                          
  12059.                                                                                 
  12060. #ifdef   TCPIPV2                                                                
  12061. #define  TCP_DEBUG            sock_debug                                        
  12062. #endif                                                                          
  12063.                                                                                 
  12064. #ifdef   SNSTCPIP                                                               
  12065. #define  TCP_DEBUG            /* I don't know how to debug in SNS */            
  12066. #undef   DEBUG                                                                  
  12067. #endif                                                                          
  12068.                                                                                 
  12069. #ifdef   DEBUG                                                                  
  12070. #define  TCP_DEBUG_ON         TCP_DEBUG(1)                                      
  12071. #define  TCP_DEBUG_OFF        TCP_DEBUG(0)                                      
  12072. #else                                                                           
  12073. #define  TCP_DEBUG_ON         /* */                                             
  12074. #define  TCP_DEBUG_OFF        /* */                                             
  12075. #endif                                                                          
  12076.                                                                                 
  12077. /****** Preprocessor bookkeeping *************************************/         
  12078.                                                                                 
  12079. #define  Bool                 char                                              
  12080. #define  Fool                 unsigned int /* for function arguments */         
  12081. #ifndef  TRUE                                                                   
  12082. #define  TRUE                 1                                                 
  12083. #endif                                                                          
  12084. #ifndef  FALSE                                                                  
  12085. #define  FALSE                0                                                 
  12086. #endif                                                                          
  12087.                                                                                 
  12088. #define  COMMANDSIZE          12                                                
  12089.                                                                                 
  12090. #define  GOPHER_FILE          '0'                                               
  12091. #define  GOPHER_DIRECTORY     '1'                                               
  12092. #define  GOPHER_CSO           '2'                                               
  12093. #define  GOPHER_ERROR         '3'                                               
  12094. #define  GOPHER_MAC_BINHEX    '4'                                               
  12095. #define  GOPHER_DOS_BINARCH   '5'                                               
  12096. #define  GOPHER_UUENCODE      '6'                                               
  12097. #define  GOPHER_WAIS          '7'                                               
  12098. #define  GOPHER_TELNET        '8'                                               
  12099. #define  GOPHER_TN3270        'T'                                               
  12100. #define  GOPHER_BINARY        '9'                                               
  12101. #define  GOPHER_REDUNDANT     '+'                                               
  12102. #define  GOPHER_WHOIS         'w'                                               
  12103.                                                                                 
  12104. #define  READ_BYTES           1024                                              
  12105. #define  SERVER_BUF_MSGSIZE   1024                                              
  12106. #define  CLIENT_BUF_MSGSIZE   1024                                              
  12107. #define  TEXT_BYTES           1024                                              
  12108. #define  INTERNET_SIZE        256                                               
  12109. #define  RBUFSIZE             256                                               
  12110. #define  OUTBUFSIZE           1024                                              
  12111.                                                                                 
  12112. #define  GOPHER_PORT_NUMBER   70                                                
  12113. #define  GOPHER_HOST_LENGTH   MAXHOSTNAMELEN                                    
  12114. #define  GOPHER_PATH_LENGTH   512                                               
  12115. #define  GOPHER_DESC_LENGTH   256                                               
  12116.                                                                                 
  12117. #define  SOCKET_GETCHAR_ERROR (-1)                                              
  12118. #define  SOCKET_NO_MORE       (-2)                                              
  12119. #define  SOCKET_READ_NOTHING  (-3)                                              
  12120.                                                                                 
  12121. #define  NO_VALUE             (-1)                                              
  12122.                                                                                 
  12123. #define  Rstruc               register struct                                   
  12124.                                                                                 
  12125. #define  EQUAL                !strcmp                                           
  12126. #define  UNEQUAL              strcmp                                            
  12127. #define  COPY(A,B)            strncpy((A),(B),sizeof(A)-1)                      
  12128.                                                                                 
  12129. #define  FIND_NEXT            'N'                                               
  12130. #define  FIND_FIRST           'F'                                               
  12131. #define  FIND_LAST            'L'                                               
  12132. #define  FIND_PREV            'P'                                               
  12133. #define  FIND_ALL             'A'                                               
  12134. #define  FIND_CHARS           '\0'                                              
  12135. #define  FIND_WORD            'W'                                               
  12136. #define  FIND_PREFIX          'P'                                               
  12137. #define  FIND_SUFFIX          'S'                                               
  12138. #define  FIND_CAPS            '\0'                                              
  12139. #define  FIND_ASIS            'A'                                               
  12140. #define  FIND_HEX             'X'                                               
  12141. #define  FIND_GENERIC         'P'                                               
  12142. #define  FIND_BADFORM         '\0'                                              
  12143. #define  FIND_UNQUOTED        'U'                                               
  12144. #define  FIND_QUOTED          'Q'                                               
  12145. #define  FIND_C               'C'                                               
  12146. #define  FIND_X               'X'                                               
  12147. #define  FIND_T               'T'                                               
  12148. #define  FIND_P               'P'                                               
  12149.                                                                                 
  12150. #define  MAX_INT               (int)0x7fffffff                                  
  12151. #define  LOCATE_INT            (int)0x7ffffffe                                  
  12152.                                                                                 
  12153. enum     scroll    {NO_SCROLL, UP, DOWN, LEFT, RIGHT, LOCATE};                  
  12154. enum     extreq    {EXTRACT_IT, PRINT_IT, BOOKMARK_IT};                         
  12155.                                                                                 
  12156. #define  CARRIAGE_RETURN      ('\r')                                            
  12157.                                                                                 
  12158. #ifdef   MVS                                                                    
  12159. #ifdef   I370                                                                   
  12160. #define  LINE_FEED            (0x15)                                            
  12161. #else                                                                           
  12162. #define  LINE_FEED            (0x25)                                            
  12163. #endif                                                                          
  12164. #else                                                                           
  12165. #define  LINE_FEED            (0x0a)                                            
  12166. #endif                                                                          
  12167.                                                                                 
  12168. #ifdef   MVS                                                                    
  12169. #ifdef   SNSTCPIP                                                               
  12170. #define  EtoA                 etoa                                              
  12171. #define  AtoE                 atoe                                              
  12172. #else                                                                           
  12173. #ifdef   I370                                                                   
  12174. #define  EtoA                 htoncs                                            
  12175. #define  AtoE                 ntohcs                                            
  12176. #else                                                                           
  12177. #define  EtoA(x)              ebcdictoascii[x]                                  
  12178. #define  AtoE(x)              asciitoebcdic[x]                                  
  12179. #define  ebcdictoascii        ebcdicto                                          
  12180. #define  asciitoebcdic        asciitoe                                          
  12181. #endif                                                                          
  12182. #endif                                                                          
  12183. #endif                                                                          
  12184.                                                                                 
  12185. #ifdef SNSTCPIP                                                                 
  12186. #define EBCDIC_TO_ASCII(A,B) EtoA(A,B)                                          
  12187. #define ASCII_TO_EBCDIC(A,B) AtoE(A,B)                                          
  12188. #else                                                                           
  12189. #define EBCDIC_TO_ASCII(A,B) {int _i; \                                         
  12190.                               for (_i=0; _i<(B); ++_i) \                        
  12191.                                   (A)[_i] = EtoA((A)[_i]); \                    
  12192.                              }                                                  
  12193. #define ASCII_TO_EBCDIC(A,B) {int _i; \                                         
  12194.                               for (_i=0; _i<(B); ++_i) \                        
  12195.                                   (A)[_i] = AtoE((A)[_i]); \                    
  12196.                              }                                                  
  12197. #endif                                                                          
  12198.                                                                                 
  12199. #ifdef TCPIPV1                                                                  
  12200. #define REPORT_TCP_ERROR(A)  /* */                                              
  12201. #endif                                                                          
  12202.                                                                                 
  12203. #ifdef TCPIPV2                                                                  
  12204. #define REPORT_TCP_ERROR(A)  tcperror(A)                                        
  12205. #endif                                                                          
  12206.                                                                                 
  12207. #ifdef SNSTCPIP                                                                 
  12208. #define REPORT_TCP_ERROR(A)  fprintf(stderr,\                                   
  12209.                                     "\nTCP error on %s: errno = %d\n",\         
  12210.                                     A,GET_ERRNO)                                
  12211. #endif                                                                          
  12212.                                                                                 
  12213. #ifdef SNSTCPIP                                                                 
  12214. #define Accept(A,B,C)        accept((A),(struct sockaddr *)(B),(C))             
  12215. #define Bind(A,B,C)          bind((A),(struct sockaddr *)(B),(C))               
  12216. #define Connect(A,B,C)       connect((A),(struct sockaddr *)(B),(C))            
  12217. #define Gethostbyaddr(A,B,C) gethostbyaddr((char *)(A),(B),(C))                 
  12218. #define Getpeername(A,B,C)   getpeername((A),(struct sockaddr *)(B),(C))        
  12219. #define Getsockopt(A,B,C,D,E) getsockopt((A),(B),(C),(char *)(D),(E))           
  12220. #define EWOULDBLOCK          (ESWOULDBLOCK+s0skcfg.errnobase)                   
  12221. #else                                                                           
  12222. #define Accept               accept                                             
  12223. #define Bind                 bind                                               
  12224. #define Connect              connect                                            
  12225. #define Gethostbyaddr        gethostbyaddr                                      
  12226. #define Getpeername          getpeername                                        
  12227. #define Getsockopt           getsockopt                                         
  12228. #endif                                                                          
  12229.                                                                                 
  12230. #ifdef   FETCH                                                                  
  12231. #define  ISPLINK              (gp->isplink_pointer)                             
  12232. #define  ISPEXEC              (gp->ispexec_pointer)                             
  12233. #else                                                                           
  12234. #define  ISPLINK              isplink                                           
  12235. #define  ISPEXEC              ispexec                                           
  12236. #endif                                                                          
  12237.                                                                                 
  12238. #define  DATAOUT_LOW          0x01                                              
  12239. #define  DATAOUT_HIGH         0x02                                              
  12240. #define  DATAIN_LOW           0x03                                              
  12241. #define  DATAIN_HIGH          0x04                                              
  12242. #define  DATAOUT_BLUE         DATAOUT_LOW                                       
  12243. #define  DATAOUT_GREEN        0x05                                              
  12244. #define  DATAOUT_PINK         0x06                                              
  12245. #define  DATAOUT_RED          0x07                                              
  12246. #define  DATAOUT_TURQ         0x08                                              
  12247. #define  DATAOUT_WHITE        DATAOUT_HIGH                                      
  12248. #define  DATAOUT_YELLOW       0x09                                              
  12249. #define  DATAIN_BLUE          0x0a                                              
  12250. #define  DATAIN_GREEN         DATAIN_LOW                                        
  12251. #define  DATAIN_PINK          0x0b                                              
  12252. #define  DATAIN_RED           DATAIN_HIGH                                       
  12253. #define  DATAIN_TURQ          0x0c                                              
  12254. #define  DATAIN_WHITE         0x0d                                              
  12255. #define  DATAIN_YELLOW        0x0e                                              
  12256.                                                                                 
  12257. #define  S99VRBAL  0x01             /* ALLOCATION                    */         
  12258. #define  S99VRBUN  0x02             /* UNALLOCATION                  */         
  12259. #define  S99VRBCC  0x03             /* CONCATENATION                 */         
  12260. #define  S99VRBDC  0x04             /* DECONCATENATION               */         
  12261. #define  S99VRBRI  0x05             /* REMOVE IN-USE                 */         
  12262. #define  S99VRBDN  0x06             /* DDNAME ALLOCATION             */         
  12263. #define  S99VRBIN  0x07             /* INFORMATION RETRIEVAL         */         
  12264. #define  S99NOCNV  0x40             /* ALLOC FUNCTION-DO NOT USE AN  */         
  12265.                                     /* EXISTING ALLOCATION TO SATISFY*/         
  12266.                                     /* THE REQUEST                   */         
  12267. #define  DALDDNAM   0x0001          /* DDNAME                        */         
  12268. #define  DALDSNAM   0x0002          /* DSNAME                        */         
  12269. #define  DALMEMBR   0x0003          /* MEMBER NAME                   */         
  12270. #define  DALSTATS   0x0004          /* DATA SET STATUS               */         
  12271. #define  DALNDISP   0x0005          /* DATA SET DISPOSITION          */         
  12272. #define  DALTRK     0x0007          /* TRACK SPACE TYPE              */         
  12273. #define  DALBLKLN   0x0009          /* BLOCK LENGTH                  */         
  12274. #define  DALPRIME   0x000a          /* PRIMARY SPACE ALLOCATION      */         
  12275. #define  DALSECND   0x000b          /* SECONDARY SPACE ALLOCATION    */         
  12276. #define  DALDIR     0x000c          /* DIRECTORY BLOCK ALLOCATION    */         
  12277. #define  DALSYSOU   0x0018          /* SYSOUT                        */         
  12278. #define  DALSFMNO   0x001a          /* SYSOUT FORMS NUMBER           */         
  12279. #define  DALCOPYS   0x001d          /* SYSOUT COPIES                 */         
  12280. #define  DALUCS     0x0029          /* UNIVERSAL CHARACTER SET       */         
  12281. #define  DALBLKSZ   0x0030          /* DCB BLOCKSIZE                 */         
  12282. #define  DALDSORG   0x003c          /* DATA SET ORGANIZATION         */         
  12283. #define  DALLRECL   0x0042          /* DCB LOGICAL RECORD LENGTH     */         
  12284. #define  DALRECFM   0x0049          /* DCB RECORD FORMAT             */         
  12285. #define  DALPERMA   0x0052          /* PERMANENTLY ALLOCATED ATTRIB  */         
  12286. #define  DALRTDDN   0x0055          /* RETURN DDNAME                 */         
  12287. #define  DALRTDSN   0x0056          /* RETURN DSNAME                 */         
  12288. #define  DALRTORG   0x0057          /* RETURN D.S. ORGANIZATION      */         
  12289. #define  DALSUSER   0x0058          /* SYSOUT REMOTE WORKSTATION     */         
  12290. #define  DUNDDNAM   0x0001          /* DDNAME                        */         
  12291. #define  DUNDSNAM   0x0002          /* DSNAME                        */         
  12292. #define  DUNUNALC   0x0007          /* UNALLOC OPTION                */         
  12293.                                                                                 
  12294. #define  SHR        0x08                                                        
  12295. #define  NEW        0x04                                                        
  12296. #define  MOD        0x02                                                        
  12297. #define  OLD        0x01                                                        
  12298. #define  KEEP       0x08                                                        
  12299. #define  DELETE     0x04                                                        
  12300. #define  CATLG      0x02                                                        
  12301. #define  UNCATLG    0x01                                                        
  12302. #define  RECFM_F    0x80                                                        
  12303. #define  RECFM_V    0x40                                                        
  12304. #define  RECFM_U    0xc0                                                        
  12305. #define  RECFM_D    0x20                                                        
  12306. #define  RECFM_T    0x20                                                        
  12307. #define  RECFM_B    0x10                                                        
  12308. #define  RECFM_S    0x08                                                        
  12309. #define  RECFM_A    0x04                                                        
  12310. #define  RECFM_M    0x02                                                        
  12311. #define  RECFM_FB   (RECFM_F | RECFM_B)                                         
  12312. #define  RECFM_VB   (RECFM_V | RECFM_B)                                         
  12313. #define  DSORG_PS   0x4000                                                      
  12314. #define  DSORG_PO   0x0200                                                      
  12315.                                                                                 
  12316.                                                                                 
  12317. /****** Data and structure definitions. ******************************/         
  12318.                                                                                 
  12319. typedef struct _textunit     TEXTUNIT;                                          
  12320. typedef unsigned int         IPADDRESS;                                         
  12321. typedef int                  SOCKETNO;                                          
  12322. typedef char                 gophertype;                                        
  12323. typedef enum     scroll      SCROLL;                                            
  12324. typedef enum     extreq      EXTREQ;                                            
  12325.                                                                                 
  12326. enum socket_retval  {                                                           
  12327.                      SERVER_READ_OK,                                            
  12328.                      SERVER_READ_ERROR,                                         
  12329.                      SERVER_BUFFER_ERROR,                                       
  12330.                      SERVER_NO_MORE,                                            
  12331.                      SERVER_READ_NOTHING                                        
  12332.                     };                                                          
  12333.                                                                                 
  12334. enum data_set_type  {                                                           
  12335.                      PDS,                                                       
  12336.                      SEQ,                                                       
  12337.                      UNK,                                                       
  12338.                      JES                                                        
  12339.                     };                                                          
  12340.                                                                                 
  12341. enum user_option    {                                                           
  12342.                      OPTION_ALL,                                                
  12343.                      OPTION_VIEW,                                               
  12344.                      OPTION_OTHER                                               
  12345.                     };                                                          
  12346.                                                                                 
  12347. struct textline    {                                                            
  12348.                     struct textline    *next;                                   
  12349.                     short               text_length;                            
  12350.                     short               tab_expanded_text_length;               
  12351.                     char               *tab_expanded_text;                      
  12352.                     char                text[1];  /* dummy */                   
  12353.                    };                                                           
  12354.                                                                                 
  12355. struct texthdr     {                                                            
  12356.                     int                   text_line_count;                      
  12357.                     struct textline      *text_body_line;                       
  12358.                     short                 text_max_length;                      
  12359.                     short                 text_max_tab_expanded_length;         
  12360.                     struct textline      *first_text_line;                      
  12361.                     struct textline      *current_text_line;                    
  12362.                     struct textline      *last_text_line;                       
  12363.                    };                                                           
  12364.                                                                                 
  12365. struct cmddesc   {                                                              
  12366.                   char    command_name[COMMANDSIZE];                            
  12367.                   Bool    (*command_processor)();                               
  12368.                  };                                                             
  12369.                                                                                 
  12370. struct seldesc   {                                                              
  12371.                   char    selection_code;                                       
  12372.                   Bool    (*selection_processor)();                             
  12373.                  };                                                             
  12374.                                                                                 
  12375. struct tabledesc {                                                              
  12376.                   char   *command_variable;                                     
  12377.         struct cmddesc   *first_cmddesc;                                        
  12378.         struct seldesc   *first_seldesc;                                        
  12379.                  };                                                             
  12380.                                                                                 
  12381. struct _textunit {                                                              
  12382.                   unsigned short         key;                                   
  12383.                   unsigned short         num;                                   
  12384.                   struct {                                                      
  12385.                           unsigned short len;                                   
  12386.                           char           prm[80];                               
  12387.                          }               ent;                                   
  12388.                  };                                                             
  12389.                                                                                 
  12390. struct extraction {                                                             
  12391.                    int                   from_number;                           
  12392.                    int                   to_number;                             
  12393.                    int                   count;                                 
  12394.                    enum data_set_type    mode;                                  
  12395.                    void                (*closer)();                             
  12396.                    Bool                  appending;                             
  12397.                    Bool                  blanking;                              
  12398.                    Bool                  tab_expanding;                         
  12399.                    EXTREQ                ex;                                    
  12400.                    char                  panelname     [9];                     
  12401.                    char                  dsname       [65];                     
  12402.                    char                  separator    [81];                     
  12403.                    char                  member_prefix [9];                     
  12404.                    char                  ddname        [9];                     
  12405.                    char                  member        [9];                     
  12406.                   };                                                            
  12407.                                                                                 
  12408. struct gopherinfo {                                                             
  12409.                    gophertype            type;                                  
  12410.                    int                   port;                                  
  12411.                    struct texthdr        thdr;                                  
  12412.                    char                  path [GOPHER_PATH_LENGTH+1];           
  12413.                    char                  host [GOPHER_HOST_LENGTH+1];           
  12414.                    char                  desc [GOPHER_DESC_LENGTH+1];           
  12415.                    char                  bmds [65]; /* bookmark file */         
  12416.                   };                                                            
  12417.                                                                                 
  12418. struct recvstruct {                                                             
  12419.     int             sockfd;   /* socket descriptor for socket call */           
  12420.     int             outlen;                                                     
  12421.     int             myport;                                                     
  12422.     FILE           *outfp;    /* used by local (non-socket) interface*/         
  12423.     FILE           *readfile;                 /* declare the file... */         
  12424.     char           *fileptr;                                                    
  12425.     char           *wargptr;                                                    
  12426.     char           *mytelnet;                                                   
  12427.     char           *mydomain;                                                   
  12428.     struct hostent  clienthostent;                                              
  12429.     char            myname  [MAXHOSTNAMELEN+1];                                 
  12430.     char            hostname[MAXHOSTNAMELEN+1];  /* client host name */         
  12431.     char            hosttest[MAXHOSTNAMELEN+1];  /* client host name */         
  12432.     char            buffer  [RBUFSIZE]; /* client's character string */         
  12433.     char            dsname  [RBUFSIZE];                                         
  12434.     char            sockbuf [OUTBUFSIZE];    /* socket output buffer */         
  12435.    };                                                                           
  12436.                                                                                 
  12437. struct menuitem {                                                               
  12438.     char          type;                  /* type of record to send   */         
  12439.     char          desc     [GOPHER_DESC_LENGTH+1];                              
  12440.     char          select   [GOPHER_PATH_LENGTH+1];                              
  12441.     char          hostname [GOPHER_HOST_LENGTH+1];                              
  12442.     int           port;                  /* host port to connect to  */         
  12443.    };                                                                           
  12444.                                                                                 
  12445. struct connection  {                                                            
  12446.              char   *server_buf;                                                
  12447.              char   *client_buf;                                                
  12448.               int    mybufl;                                                    
  12449.               int    nbytes;                                                    
  12450.               int    ibuflen;                                                   
  12451.               int    bytes_returned;                                            
  12452.               int    buf_index;                                                 
  12453.          SOCKETNO    ns;                                                        
  12454.              Bool    time_to_go_home;                                           
  12455.              Bool    server_has_something_pending;                              
  12456.              Bool    server_finished_replying;                                  
  12457.              Bool    sending_text;                                              
  12458.              Bool    receiving_text;                                            
  12459.              Bool    dont_read;                                                 
  12460.              Bool    connected_to_server;                                       
  12461.              Bool    connection_broken;                                         
  12462.              Bool    closing_connection;                                        
  12463.              Bool    reconnect_in_progress;                                     
  12464.              char    buf [READ_BYTES];                                          
  12465.                    };                                                           
  12466.                                                                                 
  12467.                                                                                 
  12468. struct ggcb {                                                                   
  12469.              char    *gopher_command;                                           
  12470.              char    *extract_separator_line;                                   
  12471.              char    *mytelnet;                                                 
  12472.              char    *mydomain;                                                 
  12473.              FILE    *debug_file;                                               
  12474.              FILE    *extract_file;                                             
  12475.   struct recvstruct  *recvp;                                                    
  12476.   struct extraction  *extractionp;                                              
  12477.   struct gopherinfo  *ginfo;                                                    
  12478. #ifdef FETCH                                                                    
  12479.               int   (*isplink_pointer)();                                       
  12480.               int   (*ispexec_pointer)();                                       
  12481. #endif                                                                          
  12482.               int     ispfrc;                                                   
  12483.               int     text_find_left_bound;                                     
  12484.               int     text_find_right_bound;                                    
  12485.               int     myport;                                                   
  12486.              Bool     test_mode;                                                
  12487.              Bool     debug_mode;                                               
  12488.              Bool     quit;                                                     
  12489.              Bool     local_mode;                                               
  12490.              Bool     extract_tab_expanding;                                    
  12491.              Bool     extract_appending;                                        
  12492.              Bool     extract_blank_before_separator;                           
  12493.              Bool     extract_write_error;                                      
  12494.              Bool     extract_close_error;                                      
  12495.              Bool     warn_overwrite;                                           
  12496.              Bool     warn_append;                                              
  12497.              Bool     setmsg;                                                   
  12498.              Bool     autoscroll;                                               
  12499.              Bool     autocursor;                                               
  12500.              Bool     setcursor;                                                
  12501.              Bool     printing;                                                 
  12502.         IPADDRESS     client_ip_address;                                        
  12503.         IPADDRESS     server_ip_address;                                        
  12504.    struct texthdr     thdr;                                                     
  12505.    struct connection  gopher_connection;                                        
  12506.              char     client_ip_addrstr   [16];                                 
  12507.              char     server_ip_addrstr   [16];                                 
  12508.              char     ggserver            [MAXHOSTNAMELEN+1];                   
  12509.              char     ggclient            [MAXHOSTNAMELEN+1];                   
  12510.              char     client_hostname     [MAXHOSTNAMELEN+1];                   
  12511.              char     server_hostname     [MAXHOSTNAMELEN+1];                   
  12512.              char     text_find_string    [81];                                 
  12513.              char     text_dispchar;                                            
  12514.              char     text_find_what;                                           
  12515.              char     text_find_type;                                           
  12516.              char     text_find_trans;                                          
  12517.              char     current_bookmark_ds [65];                                 
  12518.             };                                                                  
  12519.                                                                                 
  12520. #ifdef MVS                                                                      
  12521. #ifndef I370                                                                    
  12522. extern char                 ebcdictoascii[];                                    
  12523. extern char                 asciitoebcdic[];                                    
  12524. #endif                                                                          
  12525. #endif                                                                          
  12526.                                                                                 
  12527. #ifndef FETCH                                                                   
  12528. extern int                  isplink();                                          
  12529. extern int                  ispexec();                                          
  12530. #endif                                                                          
  12531.                                                                                 
  12532. #ifdef   ISPFV3                                                                 
  12533. #define  ZERRLM_SIZE          513                                               
  12534. #else                                                                           
  12535. #define  ZERRLM_SIZE          73                                                
  12536. #endif                                                                          
  12537.                                                                                 
  12538. #define  NOTIFY_MSG   1                                                         
  12539. #define  WARNING_MSG  2                                                         
  12540. #define  CRITICAL_MSG 3                                                         
  12541.                                                                                 
  12542. #define  WARN1(X)           GGMpmsg(gp,NOTIFY_MSG,NULL,X)                       
  12543. #define  WARN2(X,Y)         GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y)                     
  12544. #define  WARN3(X,Y,Z)       GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y,Z)                   
  12545. #define  WARN4(X,Y,Z,W)     GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y,Z,W)                 
  12546. #define  ERR1(X)            GGMpmsg(gp,WARNING_MSG,NULL,X)                      
  12547. #define  ERR2(X,Y)          GGMpmsg(gp,WARNING_MSG,NULL,X,Y)                    
  12548. #define  ERR3(X,Y,Z)        GGMpmsg(gp,WARNING_MSG,NULL,X,Y,Z)                  
  12549. #define  ERR4(X,Y,Z,W)      GGMpmsg(gp,WARNING_MSG,NULL,X,Y,Z,W)                
  12550. #define  CRIT1(X)           GGMpmsg(gp,CRITICAL_MSG,NULL,X)                     
  12551. #define  CRIT2(X,Y)         GGMpmsg(gp,CRITICAL_MSG,NULL,X,Y)                   
  12552. #define  CRIT3(X,Y,Z)       GGMpmsg(gp,CRITICAL_MSG,NULL,X,Y,Z)                 
  12553.                                                                                 
  12554. #define  GETMAIN(Ptr,Typ,Siz,For) \                                             
  12555.          GGMgetm(gp,(char **)&(Ptr),(sizeof(Typ))*(Siz),For)                    
  12556.                                                                                 
  12557. #define  FREEMAIN(Ptr,For)    if (Ptr) {GGMfreem(gp,(char *)Ptr,For);}          
  12558.                                                                                 
  12559. #ifndef I370                                                                    
  12560.                                                                                 
  12561. #define  WRITE_FILEMODE     "w,recfm=vb,lrecl=259,blksize=6233"                 
  12562. #define  APPEND_FILEMODE    "a,recfm=vb,lrecl=259,blksize=6233"                 
  12563. #define  SYSOUT_FILEMODE    "w,recfm=vba,lrecl=133"                             
  12564. #define  FILEMODE             "recfm=vb,lrecl=259,blksize=6233"                 
  12565. #define  FILEMODE_A           "recfm=vba,lrecl=133"                             
  12566.                                                                                 
  12567. #define  OPEN_TEXT_FILE_FOR_WRITE(F)  \                                         
  12568.          fopen((F),WRITE_FILEMODE)                                              
  12569.                                                                                 
  12570. #define  OPEN_TEXT_FILE_FOR_APPEND(F)  \                                        
  12571.          fopen((F),APPEND_FILEMODE)                                             
  12572.                                                                                 
  12573. #define  OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                             
  12574.          fopen((F),(B) ? APPEND_FILEMODE : WRITE_FILEMODE)                      
  12575.                                                                                 
  12576. #define  OPEN_OUTPUT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                           
  12577.          fopen((F),(B) ? "a" : WRITE_FILEMODE)                                  
  12578.                                                                                 
  12579. #define  OPEN_SYSOUT_FILE(F)  \                                                 
  12580.          fopen((F),SYSOUT_FILEMODE)                                             
  12581.                                                                                 
  12582. #define  TEST_IF_FILE_EXISTS(P,F)  (P=fopen((F),"r"))                           
  12583. #define  CLEANUP_IF_FILE_EXISTS(P) (void)fclose(P)                              
  12584.                                                                                 
  12585. #else                                                                           
  12586.                                                                                 
  12587. #define  WRITE_FILEMODE     "w,recfm=v,lrecl=255,blksize=6233"                  
  12588. #define  APPEND_FILEMODE    "a,recfm=v,lrecl=255,blksize=6233"                  
  12589. #define  SYSOUT_FILEMODE    "w,recfm=va,lrecl=133"                              
  12590. #define  FILEMODE             "recfm=v,lrecl=255,blksize=6233"                  
  12591. #define  FILEMODE_A           "recfm=va,lrecl=133"                              
  12592.                                                                                 
  12593. #define  OPEN_TEXT_FILE_FOR_WRITE(F)  \                                         
  12594.          afopen((F),"w","seq",FILEMODE)                                         
  12595.                                                                                 
  12596. #define  OPEN_TEXT_FILE_FOR_APPEND(F)  \                                        
  12597.          afopen((F),"a","seq",FILEMODE)                                         
  12598.                                                                                 
  12599. #define  OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                             
  12600.          afopen((F),(B)?"a":"w","seq",FILEMODE)                                 
  12601.                                                                                 
  12602. #define  OPEN_OUTPUT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                           
  12603.          afopen((F),(B)?"a":"w","seq",FILEMODE)                                 
  12604.                                                                                 
  12605. #define  OPEN_SYSOUT_FILE(F)  \                                                 
  12606.          afopen((F),"w","seq",FILEMODE_A)                                       
  12607.                                                                                 
  12608. #define  TEST_IF_FILE_EXISTS(F,P)  (access((F),0) == 0)                         
  12609. #define  CLEANUP_IF_FILE_EXISTS(P) /* */                                        
  12610.                                                                                 
  12611. #endif                                                                          
  12612.                                                                                 
  12613. #define ebdtoasc(C) {char *__cp;\                                               
  12614.                      for(__cp = C;*__cp;__cp++) *__cp = EtoA(*__cp);}           
  12615.                                                                                 
  12616. #define asctoebd(C) {char *__cp;\                                               
  12617.                      for(__cp = C;*__cp;__cp++) *__cp = AtoE(*__cp);}           
  12618.                                                                                 
  12619. #define uppercase_in_place(C) {char *__cp;\                                     
  12620.                      for(__cp=C;*__cp;__cp++) *__cp = toupper(*__cp);}          
  12621.                                                                                 
  12622. #define lowercase_in_place(C) {char *__cp;\                                     
  12623.                      for(__cp=C;*__cp;__cp++) *__cp = tolower(*__cp);}          
  12624.                                                                                 
  12625. #define copy_uppercase(A,B) {char *__cA,*__cB;\                                 
  12626.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12627.                          *__cA = toupper(*__cB);\                               
  12628.                      *__cA='\0';}                                               
  12629.                                                                                 
  12630. #define copy_lowercase(A,B) {char *__cA,*__cB;\                                 
  12631.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12632.                          *__cA = tolower(*__cB);\                               
  12633.                      *__cA='\0';}                                               
  12634.                                                                                 
  12635. #define copy_uppercase_and_strip_trailing(A,B,C) {char *__cA,*__cB;\            
  12636.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12637.                          *__cA = toupper(*__cB);\                               
  12638.                      for (; __cA>A && isspace(*(__cA-1)); __cA--);\             
  12639.                      *__cA='\0';C=__cA;}                                        
  12640.                                                                                 
  12641. #define copy_lowercase_and_strip_trailing(A,B,C) {char *__cA,*__cB;\            
  12642.                      for (__cA=A,__cB=B; *__cB;__cA++,__cB++)\                  
  12643.                          *__cA = tolower(*__cB);\                               
  12644.                      for (; __cA>A && isspace(*(__cA-1)); __cA--);\             
  12645.                      *__cA='\0';C=__cA;}                                        
  12646.                                                                                 
  12647. #define skip_whitespace(C)        (C) + strspn((C)," \t")                       
  12648. #define skip_ISPF_whitespace(C)   (C) + strspn((C)," ,\t")                      
  12649. #define find_whitespace(A,B)      if (!(A=strpbrk((B)," \t")))\                 
  12650.                                      A = strchr((B),'\0');                      
  12651. #define find_ISPF_whitespace(A,B) if (!(A=strpbrk((B)," ,\t")))\                
  12652.                                      A = strchr((B),'\0');                      
  12653.                                                                                 
  12654.                                                                                 
  12655. /****** Procedure and function declarations. *************************/         
  12656.                                                                                 
  12657. extern enum data_set_type  GGMalloc(char *, char *, enum data_set_type,         
  12658.                                                                   int);         
  12659. extern void                GGMbtext(struct ggcb *, struct texthdr *,            
  12660.                                                                FILE *);         
  12661. extern void                GGMclrtx(struct ggcb *,struct gopherinfo *);         
  12662. extern Bool                GGMconn (struct ggcb *,struct connection *);         
  12663. extern char               *GGMcopy (struct ggcb *, char *);                     
  12664. extern Bool                GGMcso  (struct ggcb *,struct gopherinfo *,          
  12665.                                                                  Fool);         
  12666. extern Bool                GGMdbm  (struct ggcb *,struct gopherinfo *);         
  12667. extern void                GGMdfail(int,__S99parms *);                          
  12668. extern Bool                GGMdir  (struct ggcb *,struct gopherinfo *,          
  12669.                                                                  Fool);         
  12670. extern void                GGMdisc (struct ggcb *,struct connection *);         
  12671. extern int                 GGMdispl(struct ggcb *, char *);                     
  12672. extern void                GGMdsopt(struct ggcb *, char *);                     
  12673. extern void                GGMdump (struct ggcb *,char *, char *, int);         
  12674. extern void                GGMesrvr(struct ggcb *,struct connection *);         
  12675. extern void                GGMfreem(struct ggcb *,char *,char *);               
  12676. extern FILE               *GGMgetds(struct ggcb *,struct extraction *);         
  12677. extern void                GGMgetm (struct ggcb *,char **,int,char *);          
  12678. extern Bool                GGMgofor(struct ggcb *,struct gopherinfo *,          
  12679.                                                                 Fool);          
  12680. extern Bool                GGMgsrvl(struct ggcb *,struct connection *,          
  12681.                                                         char **, Fool);         
  12682. extern void                GGMierr (struct ggcb *);                             
  12683. extern int                 GGMiget (struct ggcb *, char *);                     
  12684. extern void                GGMimsg (struct ggcb *, char *);                     
  12685. extern Bool                GGMinfo (struct ggcb *, struct gopherinfo *);        
  12686. extern Bool                GGMispf (struct ggcb *, char *);                     
  12687. extern Bool                GGMivget(struct ggcb *, char *, char *,int);         
  12688. extern Bool                GGMivput(struct ggcb *, char *, char *,int);         
  12689. extern Bool                GGMmenu (struct ggcb *, char *);                     
  12690. extern void                GGMmtfer(int, char*);                                
  12691. extern struct textline    *GGMouttx(struct ggcb *, char *,                      
  12692.                                                   struct gopherinfo *);         
  12693. extern Bool                GGMouts (struct recvstruct *, char *);               
  12694. extern Bool                GGMproc (struct recvstruct *);                       
  12695. extern void                GGMrbfm (struct ggcb *);                             
  12696. extern void                GGMrperr(struct ggcb *);                             
  12697. extern Bool                GGMsockt(struct ggcb *,struct connection *);         
  12698. extern void                GGMsopt (struct ggcb *,enum user_option);            
  12699. extern char               *GGMstrlc(char *, char *);                            
  12700. extern Bool                GGMtnet (struct ggcb *,struct gopherinfo *,          
  12701.                                                                  Fool);         
  12702. extern int                 GGMtso  (char *);                                    
  12703. extern char               *GGMtype (gophertype);                                
  12704. extern Bool                GGMunalc(char *);                                    
  12705. extern Bool                GGMvtx  (struct ggcb *,struct gopherinfo *,          
  12706.                                                                  Fool);         
  12707. extern Bool                GGMwais (struct ggcb *,struct gopherinfo *,          
  12708.                                                                  Fool);         
  12709. extern Bool                GGMwhois(struct ggcb *,struct gopherinfo *,          
  12710.                                                                  Fool);         
  12711. extern Bool                GGMxlist(struct ggcb *,char *);                      
  12712. extern Bool                GGMxtx  (struct ggcb *,struct gopherinfo *,          
  12713.                                                                EXTREQ);         
  12714.                                                                                 
  12715. #ifndef SUPPRESS_V_DECLARATION                                                  
  12716. extern void                GGMpmsg (struct ggcb *,int,char *,char *,            
  12717.                                                                   ...);         
  12718. #endif                                                                          
  12719.                                                                                 
  12720. ./   ADD NAME=GGSASC                                                            
  12721.                                                                                 
  12722.  /********************************************************************/         
  12723.  /*                                                                  */         
  12724.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12725.  /*                                                                  */         
  12726.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  12727.  /*                                                                  */         
  12728.  /* SAS modifications due to Dale Ingold at SAS Institute, Inc.      */         
  12729.  /*                                                                  */         
  12730.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12731.  /* including the implied warranties of merchantability and fitness, */         
  12732.  /* are expressly denied.                                            */         
  12733.  /*                                                                  */         
  12734.  /* Provided this copyright notice is included, this software may    */         
  12735.  /* be freely distributed and not offered for sale.                  */         
  12736.  /*                                                                  */         
  12737.  /* Changes or modifications may be made and used only by the maker  */         
  12738.  /* of same, and not further distributed.  Such modifications should */         
  12739.  /* be mailed to the author for consideration for addition to the    */         
  12740.  /* software and incorporation in subsequent releases.               */         
  12741.  /*                                                                  */         
  12742.  /********************************************************************/         
  12743.                                                                                 
  12744. /* ------------------- "ggsasc.h" include member ------------------- */         
  12745.                                                                                 
  12746. #ifdef SASC                                                                     
  12747.                                                                                 
  12748. #define I370                                                                    
  12749.                                                                                 
  12750. #include <dynam.h>                                                              
  12751.                                                                                 
  12752. #define FETCH                                                                   
  12753.                                                                                 
  12754.  __inline void (*fetch( const char *modname ))()                                
  12755.  {                                                                              
  12756.    void (*fpp)();                                                               
  12757.                                                                                 
  12758.    loadm( modname, &fpp );                                                      
  12759.    return( fpp );                                                               
  12760.  }                                                                              
  12761.                                                                                 
  12762.  __inline int (*release( void (*fpp)() ))                                       
  12763.  {                                                                              
  12764.    unloadm( fpp );                                                              
  12765.    return( 0 );                                                                 
  12766.  }                                                                              
  12767.                                                                                 
  12768.                                                                                 
  12769. #ifndef __SVC99                                                                 
  12770.                                                                                 
  12771.   #define __SVC99  1                                                            
  12772.                                                                                 
  12773.   #include <code.h>                                                             
  12774.                                                                                 
  12775.   struct __S99struc                                                             
  12776.     {                                                                           
  12777.       unsigned char   __S99RBLN;  /* length of request block..20      */        
  12778.       unsigned char   __S99VERB;  /* verb code                        */        
  12779.       unsigned short  __S99FLAG1; /* FLAGS1 field of SVC99 Req Block  */        
  12780.       unsigned short  __S99ERROR; /* error code field                 */        
  12781.       unsigned short  __S99INFO;  /* information reason code          */        
  12782.       void           *__S99TXTPP; /* address of text unit pointer list*/        
  12783.       int             __reserved; /* reserved..will always be 0       */        
  12784.       unsigned int    __S99FLAG2; /* FLAGS2 field..can only be filled */        
  12785.                                   /* in by APF authorized programs    */        
  12786.     };                                                                          
  12787.                                                                                 
  12788.   typedef struct __S99struc __S99parms;                                         
  12789.                                                                                 
  12790.   __inline int svc99(__S99parms* svc99parmlist)                                 
  12791.     { return( (_ldregs(R1, &svc99parmlist),                                     
  12792.                _code(0, 0x0a63),                                                
  12793.                _stregs(R15) ) );                                                
  12794.     }                                                                           
  12795.                                                                                 
  12796. #endif                                                                          
  12797.                                                                                 
  12798. #define FALSE 0                                                                 
  12799. #define TRUE  1                                                                 
  12800.                                                                                 
  12801. #include <lcio.h>                                                               
  12802.                                                                                 
  12803. #define  MAXHOSTNAMELEN     64                                                  
  12804.                                                                                 
  12805. #define  __ctest(X)  fprintf(stderr,\                                           
  12806.                      "GGMVS: CTEST is not supported by this compiler.")         
  12807.                                                                                 
  12808. #endif                                                                          
  12809.                                                                                 
  12810. ./   ADD NAME=GGUSER,SSI=01040038                                               
  12811.                                                                                 
  12812.  /********************************************************************/         
  12813.  /*                                                                  */         
  12814.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12815.  /*                                                                  */         
  12816.  /* GOPHER server due to Shawn Hart at the University of Delaware.   */         
  12817.  /*                                                                  */         
  12818.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12819.  /* including the implied warranties of merchantability and fitness, */         
  12820.  /* are expressly denied.                                            */         
  12821.  /*                                                                  */         
  12822.  /* Provided this copyright notice is included, this software may    */         
  12823.  /* be freely distributed and not offered for sale.                  */         
  12824.  /*                                                                  */         
  12825.  /* Changes or modifications may be made and used only by the maker  */         
  12826.  /* of same, and not further distributed.  Such modifications should */         
  12827.  /* be mailed to the author for consideration for addition to the    */         
  12828.  /* software and incorporation in subsequent releases.               */         
  12829.  /*                                                                  */         
  12830.  /********************************************************************/         
  12831.                                                                                 
  12832. /* ------------------- "gguser.h" include member ------------------- */         
  12833.                                                                                 
  12834. /* Include file for locally customized values. */                               
  12835.                                                                                 
  12836. /* Define levels of C/370 and TCP/IP.  This controls support for                
  12837.  * fetching of non-C load modules and socket error reporting.                   
  12838.  */                                                                             
  12839.                                                                                 
  12840. /* #define  C370V1    /* define this if C/370 Version 1 */                      
  12841.    #define  C370V2    /* define this if C/370 Version 2 or higher */            
  12842. /* #define  SASC      /* define this if SAS/C compiler */                       
  12843.                                                                                 
  12844. /* #define  TCPIPV1   /* define this if TCP/IP Version 1 */                     
  12845.    #define  TCPIPV2   /* define this if TCP/IP Version 2 or higher */           
  12846. /* #define  SNSTCPIP  /* define this if SNS/TCPAccess    */                     
  12847.                                                                                 
  12848. /* #define  ISPFV2    /* define this if ISPF Version 2 or earlier */            
  12849.    #define  ISPFV3    /* define this if ISPF Version 3 or later   */            
  12850.                                                                                 
  12851. /*                                                                              
  12852.  * Define this if you want DEST, FORMS and UCB for print requests.              
  12853.  * Undefine it if you don't (you get just CLASS and COPIES).                    
  12854.  */                                                                             
  12855.                                                                                 
  12856.    #define FULLSYSOUT                                                           
  12857. /* #undef  FULLSYSOUT */                                                        
  12858.                                                                                 
  12859. /* Define the following defaults for your installation. */                      
  12860. /* Use XTELNET if you like the CSOCK package from UCLA. */                      
  12861.                                                                                 
  12862.    #define  TELNET_COMMAND_NAME     "TELNET"                                    
  12863. /* #define  TELNET_COMMAND_NAME     "XTELNET" */                                
  12864.                                                                                 
  12865. /* Define this if the server host name set by the "+" frob                      
  12866.  * should have the domain name appended.  Note that this will                   
  12867.  * affect how the hostname needs to be specified for a                          
  12868.  * Path=(pdsmember) specification - it must match the local host                
  12869.  * the way it is generated here.  Of course, host=+ will do it anyway.          
  12870.  */                                                                             
  12871.                                                                                 
  12872.    #define  APPEND_DOMAIN_NAME_TO_SELF                                          
  12873. /* #undef   APPEND_DOMAIN_NAME_TO_SELF */                                       
  12874.                                                                                 
  12875. /*                                                                              
  12876.  * Turn on for TCP-level debugging output (you probably don't want to           
  12877.  * unless your TCP/IP stuff is really broken and I can't help you).             
  12878.  */                                                                             
  12879.                                                                                 
  12880. /* #define DEBUG       */                                                       
  12881.    #undef  DEBUG                                                                
  12882.                                                                                 
  12883. /*                                                                              
  12884.  * Turn on for MTF-level debugging output.                                      
  12885.  */                                                                             
  12886.                                                                                 
  12887. /* #define DEBUGMTF    */                                                       
  12888.    #undef  DEBUGMTF                                                             
  12889.                                                                                 
  12890. /* Server and MTF stuff. */                                                     
  12891.                                                                                 
  12892. /* #define  MTF_TASKS           8 */                                            
  12893. #define  MTF_TASKS           1  /* lest REXX multitasking lossage */            
  12894. #define  TCP_QUEUE_LENGTH   20                                                  
  12895. #define  SERV_TCP_PORT      70                                                  
  12896. #define  CONNECT_TIME_OUT   60                                                  
  12897. #define  DEFAULT_DIRECTORY  "DD:GGGOPHER"                                       
  12898. #define  ACCESS_TABLE       "DD:GGACCESS"                                       
  12899. #define  DEBUG_FILE         "DD:GGDEBUG"                                        
  12900. #define  PARAMETER_FILE     "DD:GGPARMS"                                        
  12901. #define  MY_DOMAIN_SUFFIX   ".DRAPER.COM"                                       
  12902.                                                                                 
  12903. /* note: could get MY_DOMAIN_SUFFIX from TCPIP startup - what call? */          
  12904.                                                                                 
  12905. /* Client stuff. */                                                             
  12906.                                                                                 
  12907. #define  INITIAL_TYPE   GOPHER_DIRECTORY                                        
  12908. #define  INITIAL_PORT   GOPHER_PORT_NUMBER                                      
  12909. #define  INITIAL_PATH   ""                                                      
  12910. #define  INITIAL_HOST   "MVS.DRAPER.COM"                                        
  12911. #define  INITIAL_DESC   "Root"                                                  
  12912.                                                                                 
  12913. /* Server and client stuff. */                                                  
  12914.                                                                                 
  12915. #define  IDENT_HOST_FROB    "+"                                                 
  12916. #define  LOCAL_HOST_FROB    "-"                                                 
  12917.                                                                                 
  12918. /********************************************************************/          
  12919. /*  following are "gopher" record types.   */                                   
  12920. /********************************************************************/          
  12921.                                                                                 
  12922. #define  GFILE    '0'                                                           
  12923. #define  MENU     '1'                                                           
  12924. #define  ERROR    '2'                                                           
  12925. #define  INDEX    '7'                                                           
  12926. #define  TELNET   '8'                                                           
  12927. #define  TN3270   'T'                                                           
  12928. #define  WHOIS    'w'                                                           
  12929.                                                                                 
  12930. /********************************************************************/          
  12931. /* following are MVS file type identifiers.  They must appear at the            
  12932.    beginning of the file they're identifying.                        */         
  12933. /********************************************************************/          
  12934.                                                                                 
  12935. #define  MENUIDENT    "GOPHER_MENU"                                             
  12936. #define  INDEXIDENT   "GOPHER_INDEX"                                            
  12937.                                                                                 
  12938. /********************************************************************/          
  12939. /*  following are tokens for menu GOPHER identifiers.    */                     
  12940. /********************************************************************/          
  12941.                                                                                 
  12942. #define  TOKTYPE      "TYPE"                                                    
  12943. #define  TYPETOK      0                                                         
  12944. #define  TOKNAME      "NAME"                                                    
  12945. #define  NAMETOK      1                                                         
  12946. #define  TOKPATH      "PATH"